diff --git a/Workspace_msvc/isar_post_rend.vcxproj b/Workspace_msvc/isar_post_rend.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..19cb1aff7bc1584679d57f085677019b478a016d
--- /dev/null
+++ b/Workspace_msvc/isar_post_rend.vcxproj
@@ -0,0 +1,179 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ isar_post_rend
+ {12374ADC-0E5C-4FDD-B903-71D572413831}
+ isar_post_rend
+ 10.0.17763.0
+
+
+
+ Application
+ v141
+ false
+ MultiByte
+
+
+ Application
+ v141
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>15.0.27428.2015
+
+
+ ..\
+ .\Debug_$(ProjectName)\
+ false
+ false
+ ISAR_post_rend
+
+
+ ..\
+ .\Release_$(ProjectName)\
+ false
+ false
+ ISAR_post_rend
+
+
+
+ $(IntDir)$(ProjectName).tlb
+
+
+
+ Disabled
+ ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories)
+ _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions)
+
+ EnableFastChecks
+ MultiThreadedDebug
+ false
+
+
+ $(IntDir)$(ProjectName).pdb
+ Level4
+ true
+ OldStyle
+ Default
+ %(DisableSpecificWarnings)
+ false
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0c0c
+
+
+
+ $(OutDir)$(TargetName).exe
+ true
+
+ true
+ $(IntDir)$(ProjectName).pdb
+ Console
+ false
+
+ MachineX86
+
+
+
+
+ $(IntDir)$(ProjectName).tlb
+
+
+
+ MaxSpeed
+ AnySuitable
+ false
+ Neither
+ false
+ false
+ ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories)
+ _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)
+ true
+
+ Default
+ MultiThreaded
+ true
+ Precise
+ false
+
+
+ $(IntDir)$(ProjectName).pdb
+ Level4
+ true
+
+ Default
+ %(DisableSpecificWarnings)
+ false
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0c0c
+
+
+ $(OutDir)$(TargetName).exe
+ true
+
+ false
+ $(IntDir)$(ProjectName).pdb
+ Console
+ false
+
+ MachineX86
+ libcmtd.lib
+
+
+
+
+
+
+
+
+
+ {54509728-928B-44D9-A118-A6F92F08B34F}
+ false
+
+
+ {869a305e-d99e-4c3a-bdb3-aa57abcce619}
+
+
+ {2FA8F384-0775-F3B7-F8C3-85209222FC70}
+ false
+
+
+ {39ec200d-7795-4ff8-b214-b24eda5526ae}
+ false
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..c663ef5e7c108e2da838e40102a17b6e99a1648d
--- /dev/null
+++ b/Workspace_msvc/lib_isar.vcxproj
@@ -0,0 +1,202 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ lib_isar
+ {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}
+ evs_dec
+ 10.0.17763.0
+
+
+ StaticLibrary
+ v141
+ false
+ MultiByte
+
+
+
+ StaticLibrary
+ v141
+ false
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>15.0.27428.2015
+
+
+ .\Debug_$(ProjectName)\
+ .\Debug_$(ProjectName)\
+ false
+ false
+ libivasrend
+
+
+ .\Release_$(ProjectName)\
+ .\Release_$(ProjectName)\
+ false
+ false
+ libivasrend
+
+
+
+
+
+
+ .\Debug\$(ProjectName).tlb
+
+
+
+ Disabled
+ ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories)
+ _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)
+
+ EnableFastChecks
+ MultiThreadedDebug
+ false
+
+
+ $(IntDir)$(ProjectName).pdb
+ Level4
+ true
+ OldStyle
+ Default
+ %(DisableSpecificWarnings)
+ false
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0c0c
+
+
+ WS2_32.lib; %(AdditionalDependencies)
+ $(OutDir)$(TargetName).lib
+ true
+
+
+
+
+
+
+
+ $(IntDir)$(ProjectName).tlb
+
+
+
+ MaxSpeed
+ AnySuitable
+ false
+ Neither
+ false
+ false
+ ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories)
+ _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)
+ true
+
+ Default
+ MultiThreaded
+ true
+ false
+
+
+ $(IntDir)$(ProjectName).pdb
+ Level4
+ true
+
+ Default
+ %(DisableSpecificWarnings)
+ false
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0c0c
+
+
+ WS2_32.lib; %(AdditionalDependencies)
+ $(OutDir)$(TargetName).lib
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {39ec200d-7795-4ff8-b214-b24eda5526ae}
+ false
+
+
+ {54509728-928b-44d9-a118-a6f92f08b34f}
+ false
+
+
+ {95030B82-70CD-4C6B-84D4-61096035BEA2}
+ false
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..294677fff9d3b282fea8a0b6129f7b84a644b039
--- /dev/null
+++ b/Workspace_msvc/lib_lc3plus.vcxproj
@@ -0,0 +1,195 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {95030B82-70CD-4C6B-84D4-61096035BEA2}
+ Win32Proj
+ LC3_FL
+ 10.0.17763.0
+
+
+
+ StaticLibrary
+ true
+ v141
+ Unicode
+
+
+ StaticLibrary
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ liblc3plus
+ .\Debug_$(ProjectName)\
+ .\Debug_$(ProjectName)\
+
+
+ LC3plus
+ $(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\Obj\
+
+
+
+
+
+ Level3
+ ..\lib_com;%(AdditionalIncludeDirectories)
+ Disabled
+ MultiThreadedDebug
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ 4305;4244;4996
+ OldStyle
+ false
+ false
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ ..\lib_com;%(AdditionalIncludeDirectories)
+ MaxSpeed
+ MultiThreaded
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ 4244;4305;4996
+ false
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/decoder.c b/apps/decoder.c
index 05872256985800658c623b48072312c7e015b132..65c949ace14df8b8c7ba0663914f3765ed8d62d9 100644
--- a/apps/decoder.c
+++ b/apps/decoder.c
@@ -43,6 +43,9 @@
#include "masa_file_writer.h"
#include "render_config_reader.h"
#include "rotation_file_reader.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "split_render_file_read_write.h"
+#endif
#include "vector3_pair_file_reader.h"
#include "wmc_auto.h"
#include "options.h"
@@ -114,6 +117,9 @@ typedef struct
Word16 non_diegetic_pan_gain_fx; /* Q15 */
bool renderConfigEnabled;
char *renderConfigFilename;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ char *outputMdFilename;
+#endif
IVAS_DEC_COMPLEXITY_LEVEL complexityLevel;
bool tsmEnabled;
IVAS_RENDER_FRAMESIZE renderFramesize;
@@ -130,7 +136,11 @@ typedef struct
static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg );
static void usage_dec( void );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+#else
static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+#endif
static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec );
@@ -147,6 +157,10 @@ int main(
bool mainFailed = true; /* Assume main failed until cleanup is reached without errors */
DecArguments arg;
ivas_error error = IVAS_ERR_UNKNOWN;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ISAR_SPLIT_REND_BITS_DATA splitRendBits;
+ uint8_t splitRendBitsBuf[ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES];
+#endif
/* Any handles that require cleanup must be declared here and initialized to NULL */
IVAS_DEC_HANDLE hIvasDec = NULL;
@@ -166,6 +180,10 @@ int main(
reset_mem( USE_BYTES );
#endif
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ splitRendBits.bits_buf = splitRendBitsBuf;
+#endif
+
/*------------------------------------------------------------------------------------------*
* Parse command-line arguments
*------------------------------------------------------------------------------------------*/
@@ -212,6 +230,18 @@ int main(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
+ {
+ fprintf( stdout, "Output metadata file: %s\n", arg.outputWavFilename );
+ }
+ else if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename );
+ fprintf( stdout, "Output metadata file: %s\n", arg.outputMdFilename );
+ }
+ else
+#endif
{
fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename );
}
@@ -245,7 +275,11 @@ int main(
if ( arg.enableHeadRotation )
{
/* sanity check */
- if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM
+#endif
+ )
{
fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" );
goto cleanup;
@@ -345,7 +379,12 @@ int main(
if ( arg.renderConfigEnabled )
{
/* sanity check */
- if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM &&
+ arg.Opt_non_diegetic_pan == 0
+#endif
+ )
{
fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" );
goto cleanup;
@@ -381,10 +420,29 @@ int main(
fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for decoding to EXT!\n" );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
/*------------------------------------------------------------------------------------------*
* Configure Split rendering
*------------------------------------------------------------------------------------------*/
+ asked_frame_size = arg.renderFramesize;
+ if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+
+ if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg.renderFramesize ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+
+ arg.enableHeadRotation = true;
+ }
+#endif
/*------------------------------------------------------------------------------------------*
* Configure VoIP mode
@@ -410,11 +468,21 @@ int main(
IVAS_RENDER_CONFIG_DATA renderConfig;
/* sanity check */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB &&
+ arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM &&
+ arg.Opt_non_diegetic_pan == 0 )
+ {
+ fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" );
+ goto cleanup;
+ }
+#else
if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
{
fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" );
goto cleanup;
}
+#endif
if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK )
{
@@ -422,7 +490,6 @@ int main(
goto cleanup;
}
-
if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK )
{
fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename );
@@ -441,6 +508,33 @@ int main(
renderConfig.directivity_fx[i * 3 + 2] = (Word16) ( renderConfig.directivity[i * 3 + 2] * ( ( 1u << 15 ) - 1 ) );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ||
+ arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS &&
+ ( renderConfig.split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ||
+ renderConfig.split_rend_config.dof == 0 ) )
+ {
+ arg.renderFramesize = asked_frame_size;
+ }
+ else
+ {
+ arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS;
+ }
+
+ if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( arg.renderFramesize != asked_frame_size )
+ {
+ fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" );
+ }
+ }
+#endif
+
if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
{
if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK )
@@ -458,6 +552,13 @@ int main(
}
renderConfig.roomAcoustics.override = true;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /* ISAR frame size is set from command line, not renderer config file.
+ * This will be ignored if output format is not split rendering. */
+ renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) arg.renderFramesize /* given in number of 5ms subframes */ * 5;
+#endif
+#endif
if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK )
{
@@ -568,13 +669,18 @@ int main(
/*-----------------------------------------------------------------*
* Decoding
*-----------------------------------------------------------------*/
+
if ( arg.voipMode )
{
error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec );
}
else
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf );
+#else
error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf );
+#endif
}
if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE )
@@ -708,6 +814,16 @@ static IVAS_AUDIO_CONFIG cmdline2config(
{
output_config = IVAS_AUDIO_CONFIG_BINAURAL;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CODED" ) == 0 )
+ {
+ output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED;
+ }
+ else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_PCM" ) == 0 )
+ {
+ output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM;
+ }
+#endif
else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 )
{
output_config = IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR;
@@ -775,6 +891,9 @@ static bool parseCmdlIVAS_dec(
arg->renderConfigFilename = NULL;
arg->Opt_dpid_on = 0;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ arg->outputMdFilename = NULL;
+#endif
arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192;
arg->Opt_non_diegetic_pan = 0;
@@ -1022,6 +1141,19 @@ static bool parseCmdlIVAS_dec(
}
i += 2;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ else if ( strcmp( argv_to_upper, "-OM" ) == 0 )
+ {
+ arg->outputMdFilename = argv[i + 1];
+ if ( arg->outputMdFilename[0] == '\0' )
+ {
+ fprintf( stderr, "Error: output metadata file path not specified\n\n" );
+ usage_dec();
+ return false;
+ }
+ i += 2;
+ }
+#endif
else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 )
{
i++;
@@ -1172,6 +1304,14 @@ static bool parseCmdlIVAS_dec(
usage_dec();
return false;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" );
+ usage_dec();
+ return false;
+ }
+#endif
}
else
{
@@ -1248,8 +1388,13 @@ static void usage_dec( void )
fprintf( stdout, "Mandatory parameters:\n" );
fprintf( stdout, "---------------------\n" );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" );
+ fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT\n" );
+#else
fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" );
fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" );
+#endif
fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" );
fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" );
fprintf( stdout, " layout file. See readme.txt for details.\n" );
@@ -1289,6 +1434,9 @@ static void usage_dec( void )
fprintf( stdout, "-rvf File : Reference vector specified by external trajectory File\n" );
fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" );
fprintf( stdout, "-render_config File : Renderer configuration File\n" );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ fprintf( stdout, "-om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf (only for Fs = 48 kHz)\n" );
+#endif
fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" );
fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" );
fprintf( stdout, "-exof File : External orientation File for external orientation trajectory\n" );
@@ -1318,7 +1466,12 @@ static ivas_error initOnFirstGoodFrame(
IVAS_DEC_HANDLE hIvasDec, /* i/o: */
const DecArguments arg, /* i : */
const int16_t numInitialBadFrames, /* i : */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ int16_t *numOutSamples, /* i/o: */
+ int16_t *vec_pos_len, /* i/o: */
+#else
const uint16_t numOutSamples, /* i : */
+#endif
int16_t *pFullDelayNumSamples, /* o : */
int16_t *pRemainingDelayNumSamples, /* o : */
int32_t *delayTimeScale, /* o : */
@@ -1327,7 +1480,12 @@ static ivas_error initOnFirstGoodFrame(
MasaFileWriter **ppMasaWriter, /* o : */
IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */
int16_t *pNumOutChannels, /* o : */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ uint16_t *pNumObj, /* o : */
+ SplitFileReadWrite **splitRendWriter
+#else
uint16_t *pNumObj /* o : */
+#endif
)
{
ivas_error error = IVAS_ERR_UNKNOWN;
@@ -1339,6 +1497,12 @@ static ivas_error initOnFirstGoodFrame(
return error;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) )
+ {
+ pFullDelayNumSamples[0] = 0;
+ }
+#endif
if ( !arg.delayCompensationEnabled )
{
@@ -1360,22 +1524,149 @@ static ivas_error initOnFirstGoodFrame(
return error;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) )
+ {
+ /* Open split rendering metadata writer */
+ int16_t delayNumSamples_temp[3];
+ int32_t delayTimeScale_temp;
+ ISAR_SPLIT_REND_CODEC splitRendCodec;
+ int16_t splitRendCodecFrameSizeMs;
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t splitRendIsarFrameSizeMs;
+ int16_t lc3plusHighRes;
+#endif
+
+ if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) );
+ return error;
+ }
+
+ if ( ( error = IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec,
+ &splitRendCodec,
+ &poseCorrection,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ &splitRendIsarFrameSizeMs,
+#endif
+ &splitRendCodecFrameSizeMs
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ &lc3plusHighRes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to get split renderer bitstream header: %s\n", ivas_error_to_string( error ) );
+ return error;
+ }
+
+ if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) )
+ {
+ if ( ( error = split_rend_writer_open( splitRendWriter,
+ arg.outputWavFilename,
+ delayNumSamples_temp[0],
+ delayTimeScale_temp,
+ splitRendCodec,
+ poseCorrection,
+ splitRendCodecFrameSizeMs
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ splitRendIsarFrameSizeMs,
+ arg.output_Fs,
+ lc3plusHighRes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename );
+ return error;
+ }
+ }
+ else
+ {
+ if ( arg.outputMdFilename == NULL )
+ {
+ fprintf( stderr, "\nOutput split rendering metadata file not specified\n" );
+ return IVAS_ERR_INVALID_SPLIT_REND_CONFIG;
+ }
+
+ if ( ( error = split_rend_writer_open( splitRendWriter,
+ arg.outputMdFilename,
+ delayNumSamples_temp[0],
+ delayTimeScale_temp,
+ splitRendCodec,
+ poseCorrection,
+ splitRendCodecFrameSizeMs
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ splitRendIsarFrameSizeMs,
+ arg.output_Fs,
+ lc3plusHighRes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename );
+ return error;
+ }
+ }
+ }
+
+ if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 )
+ {
+#endif
/* Open audio writer and write all previously skipped bad frames now that frame size is known */
if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename );
return error;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) );
memset( zeroBuf, 0, pcmFrameSize * sizeof( int16_t ) );
for ( int16_t i = 0; i < numInitialBadFrames; ++i )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( *splitRendWriter != NULL )
+ {
+ ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero;
+ splitRendBitsZero.bits_buf = NULL;
+ splitRendBitsZero.bits_read = 0;
+ splitRendBitsZero.bits_written = 0;
+ splitRendBitsZero.buf_len = 0;
+ splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
+ splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ splitRendBitsZero.codec_frame_size_ms = 0;
+ splitRendBitsZero.isar_frame_size_ms = 20;
+#else
+ splitRendBitsZero.codec_frame_size_ms = 20;
+#endif
+ if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to write to bitstream file!\n" );
+ return error;
+ }
+ }
+ else
+ {
+#endif
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( *pRemainingDelayNumSamples < *numOutSamples )
+#else
if ( *pRemainingDelayNumSamples < numOutSamples )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK )
+#else
if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "\nOutput audio file writer error\n" );
return error;
@@ -1384,8 +1675,15 @@ static ivas_error initOnFirstGoodFrame(
}
else
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ *pRemainingDelayNumSamples -= *numOutSamples;
+#else
*pRemainingDelayNumSamples -= numOutSamples;
+#endif
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
}
+#endif
}
free( zeroBuf );
@@ -1452,6 +1750,7 @@ static ivas_error initOnFirstGoodFrame(
{
/* Duplicate good first frame metadata to fill the beginning of stream. */
IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL;
+
if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
@@ -1470,6 +1769,27 @@ static ivas_error initOnFirstGoodFrame(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( *splitRendWriter != NULL )
+ {
+ if ( numOutSamples == NULL || vec_pos_len == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ /* real setting of the 5ms mode for split rendering is only known after the decoded first good frame, reset the variables needed in the main decoding loop accordingly here*/
+ if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, numOutSamples ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError getting render frame size in samples\n" );
+ return error;
+ }
+ if ( ( error = IVAS_DEC_GetReferencesUpdateFrequency( hIvasDec, vec_pos_len ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError getting render frame size in samples\n" );
+ return error;
+ }
+ }
+#endif
return IVAS_ERR_OK;
}
@@ -1488,6 +1808,9 @@ static ivas_error decodeG192(
RotFileReader *externalOrientationFileReader,
RotFileReader *refRotReader,
Vector3PairFileReader *referenceVectorReader,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits,
+#endif
IVAS_DEC_HANDLE hIvasDec,
int16_t *pcmBuf )
@@ -1514,7 +1837,9 @@ static ivas_error decodeG192(
IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS];
IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 } };
int16_t vec_pos_update, vec_pos_len;
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ SplitFileReadWrite *splitRendWriter = NULL;
+#endif
for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i )
{
@@ -1612,18 +1937,42 @@ static ivas_error decodeG192(
{
IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
- for ( i = 0; i < num_subframes; i++ )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( headRotReader == NULL )
{
- if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK )
+ for ( i = 0; i < num_subframes; i++ )
{
- fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) );
- goto cleanup;
+ Quaternions[i].w = -3.0f;
+ Quaternions[i].x = 0.0f;
+ Quaternions[i].y = 0.0f;
+ Quaternions[i].z = 0.0f;
+ Pos[i].x = 0.0f;
+ Pos[i].y = 0.0f;
+ Pos[i].z = 0.0f;
}
}
+ else
+ {
+#endif
+ for ( i = 0; i < num_subframes; i++ )
+ {
+ if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) );
+ goto cleanup;
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
for ( i = 0; i < num_subframes; i++ )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
@@ -1681,14 +2030,38 @@ static ivas_error decodeG192(
goto cleanup;
}
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) )
+ {
+ if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+
+ nSamplesRendered += nSamplesRendered_loop;
+ nSamplesToRender -= nSamplesRendered_loop;
+ }
+ else
+ {
+#endif
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK )
+
+#else
if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
}
nSamplesRendered += nSamplesRendered_loop;
nSamplesToRender -= nSamplesRendered_loop;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
if ( needNewFrame )
{
@@ -1719,7 +2092,11 @@ static ivas_error decodeG192(
/* Once good frame decoded, catch up */
if ( decodedGoodFrame )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK )
+#else
if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK )
+#endif
{
goto cleanup;
}
@@ -1733,6 +2110,19 @@ static ivas_error decodeG192(
/* Write current frame */
if ( decodedGoodFrame )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) )
+ {
+ if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to write to bitstream file!\n" );
+ goto cleanup;
+ }
+ }
+
+ if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 )
+ {
+#endif
if ( delayNumSamples < nOutSamples )
{
if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
@@ -1746,6 +2136,9 @@ static ivas_error decodeG192(
{
delayNumSamples -= nOutSamples;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
}
/* Write ISm metadata to external file(s) */
@@ -1859,7 +2252,11 @@ static ivas_error decodeG192(
goto cleanup;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
@@ -1867,7 +2264,11 @@ static ivas_error decodeG192(
}
/* decode and get samples */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
@@ -1979,11 +2380,18 @@ static ivas_error decodeG192(
*------------------------------------------------------------------------------------------*/
memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) );
- if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( afWriter != NULL )
{
- fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
- goto cleanup;
+#endif
+ if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
+ goto cleanup;
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
}
+#endif
/*------------------------------------------------------------------------------------------*
* Close files and deallocate resources
@@ -1993,6 +2401,9 @@ static ivas_error decodeG192(
cleanup:
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ split_rend_reader_writer_close( &splitRendWriter );
+#endif
AudioFileWriter_close( &afWriter );
MasaFileWriter_close( &masaWriter );
for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ )
@@ -2239,19 +2650,44 @@ static ivas_error decodeVoIP(
{
IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
- for ( i = 0; i < num_subframes; i++ )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( headRotReader == NULL )
{
- if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK )
+ for ( i = 0; i < num_subframes; i++ )
{
- fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ),
- RotationFileReader_getFilePath( headRotReader ) );
- goto cleanup;
+ Quaternions[i].w = -3.0f;
+ Quaternions[i].x = 0.0f;
+ Quaternions[i].y = 0.0f;
+ Quaternions[i].z = 0.0f;
+ Pos[i].x = 0.0f;
+ Pos[i].y = 0.0f;
+ Pos[i].z = 0.0f;
}
}
+ else
+ {
+#endif
+ for ( i = 0; i < num_subframes; i++ )
+ {
+ if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ),
+ RotationFileReader_getFilePath( headRotReader ) );
+ goto cleanup;
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
for ( i = 0; i < num_subframes; i++ )
{
- if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK )
+ if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ,
+ DEFAULT_AXIS
+#endif
+ ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
@@ -2339,10 +2775,18 @@ static ivas_error decodeVoIP(
/* decode and get samples */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef SUPPORT_JBM_TRACEFILE
+ if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK )
+#else
+ if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK )
+#endif
+#else
#ifdef SUPPORT_JBM_TRACEFILE
if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK )
#else
if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK )
+#endif
#endif
{
fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) );
@@ -2379,8 +2823,15 @@ static ivas_error decodeVoIP(
/* Once good frame decoded, catch up */
if ( decodedGoodFrame )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ SplitFileReadWrite *splitRendWriter = NULL;
+
+ if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale,
+ &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK )
+#else
if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale,
&bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK )
+#endif
{
goto cleanup;
}
diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a8d7c3ba369105dc3c14917d7207cff7c9fe377
--- /dev/null
+++ b/apps/isar_post_rend.c
@@ -0,0 +1,1262 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "lib_isar_post_rend.h"
+//#undef IVAS_FLOAT_FIXED
+
+#ifndef SPLIT_REND_WITH_HEAD_ROT
+
+int main( int argc, char **argv )
+{
+ (void) argc;
+ (void) argv;
+ ISAR_POST_REND_void_func();
+ return 0;
+}
+
+#else
+
+#include
+#include
+#include
+#include "audio_file_reader.h"
+#include "audio_file_writer.h"
+#include "cmdl_tools.h"
+#include "cmdln_parser.h"
+#include "render_config_reader.h"
+#include "rotation_file_reader.h"
+#include "split_render_file_read_write.h"
+#include "split_rend_bfi_file_reader.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "stl.h"
+#include "wmc_auto.h"
+
+
+#define WMC_TOOL_SKIP
+
+/*------------------------------------------------------------------------------------------*
+ * Local constants
+ *------------------------------------------------------------------------------------------*/
+
+#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX )
+
+#define ISAR_MAX16B_FLT 32767.0f
+#define ISAR_MIN16B_FLT ( -32768.0f )
+#define ISAR_MAX16B_FX 32767
+#define ISAR_MIN16B_FX ( -32768 )
+
+#if !defined( DEBUGGING ) && !defined( WMOPS )
+static
+#endif
+ int32_t frame = 0;
+
+#ifdef _WIN32
+#define SEP_FOLDER '\\'
+#else
+#define SEP_FOLDER '/'
+#endif
+
+/*------------------------------------------------------------------------------------------*
+ * Local structures
+ *------------------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ IVAS_AUDIO_CONFIG audioConfig;
+ int32_t inputChannelIndex;
+ float gain_dB;
+} RendererInput;
+
+typedef struct
+{
+ RendererInput binBuses[RENDERER_MAX_BIN_INPUTS];
+ uint16_t numBinBuses;
+} InputConfig;
+
+typedef struct
+{
+ IVAS_AUDIO_CONFIG audioConfig;
+} OutputConfig;
+
+typedef struct
+{
+ char executableName[POST_REND_MAX_CLI_ARG_LENGTH];
+ char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH];
+ char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH];
+ int32_t sampleRate;
+ InputConfig inConfig;
+ OutputConfig outConfig;
+ char inMetadataFilePaths[RENDERER_MAX_ISAR_MD_INPUTS][POST_REND_MAX_CLI_ARG_LENGTH];
+ int16_t numInMetadataFiles;
+ char headRotationFilePath[POST_REND_MAX_CLI_ARG_LENGTH];
+ char splitRendBFIFilePath[POST_REND_MAX_CLI_ARG_LENGTH];
+ ISAR_POST_REND_COMPLEXITY_LEVEL complexityLevel;
+ bool delayCompensationEnabled;
+ bool quietModeEnabled;
+ bool sceneDescriptionInput;
+ IVAS_RENDER_FRAMESIZE render_framesize;
+} CmdlnArgs;
+
+typedef enum
+{
+ CmdLnOptionId_inputFile = 1,
+ CmdLnOptionId_inputFormat,
+ CmdLnOptionId_outputFile,
+ CmdLnOptionId_sampleRate,
+ CmdLnOptionId_trajFile,
+ CmdLnOptionId_orientationTracking,
+ CmdLnOptionId_complexityLevel,
+ CmdLnOptionId_noDelayCmp,
+ CmdLnOptionId_quietModeEnabled,
+ CmdLnOptionId_inputMetadata,
+ CmdLnOptionId_listFormats,
+ CmdLnOptionId_SplitRendBFIFile,
+ CmdLnOptionId_framing,
+} CmdLnOptionId;
+
+static const CmdLnParser_Option cliOptions[] = {
+ {
+ .id = CmdLnOptionId_inputFile,
+ .match = "input_file",
+ .matchShort = "i",
+ .description = "Path to the input file (WAV, raw PCM or scene description file)",
+ },
+ {
+ .id = CmdLnOptionId_inputFormat,
+ .match = "input_format",
+ .matchShort = "if",
+ .description = "Audio format of input file (e.g. BINAURAL_SPLIT_PCM, use -l for a list)",
+ },
+ {
+ .id = CmdLnOptionId_inputMetadata,
+ .match = "input_metadata",
+ .matchShort = "im",
+ .description = "Space-separated list of path to metadata files for BINAURAL_SPLIT_PCM input mode",
+ },
+ {
+ .id = CmdLnOptionId_outputFile,
+ .match = "output_file",
+ .matchShort = "o",
+ .description = "Path to the output file",
+ },
+ {
+ .id = CmdLnOptionId_sampleRate,
+ .match = "sample_rate",
+ .matchShort = "fs",
+ .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs",
+ },
+ {
+ .id = CmdLnOptionId_trajFile,
+ .match = "trajectory_file",
+ .matchShort = "T",
+ .description = "Head rotation trajectory file for simulation of head tracking",
+ },
+ {
+ .id = CmdLnOptionId_SplitRendBFIFile,
+ .match = "post_rend_bfi_file",
+ .matchShort = "prbfi",
+ .description = "Split rendering option: bfi file",
+ },
+ {
+ .id = CmdLnOptionId_noDelayCmp,
+ .match = "no_delay_compensation",
+ .matchShort = "no_delay_cmp",
+ .description = "[flag] Turn off delay compensation",
+ },
+ {
+ .id = CmdLnOptionId_complexityLevel,
+ .match = "complexity_level",
+ .matchShort = "level",
+ .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.",
+ },
+ {
+ .id = CmdLnOptionId_quietModeEnabled,
+ .match = "quiet",
+ .matchShort = "q",
+ .description = "[flag] Limit printouts to terminal",
+ },
+ {
+ .id = CmdLnOptionId_listFormats,
+ .match = "list",
+ .matchShort = "l",
+ .description = "List supported audio formats",
+ },
+ {
+ .id = CmdLnOptionId_framing,
+ .match = "framing",
+ .matchShort = "fr",
+ .description = "Set Render audio framing.",
+ },
+};
+
+
+/*------------------------------------------------------------------------------------------*
+ * Local function prototypes
+ *------------------------------------------------------------------------------------------*/
+
+static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option );
+
+static void printSupportedAudioConfigs( void );
+
+static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString );
+
+static void convertOutputBuffer( const Word32 *fixedBuffer, Word16 q, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer );
+
+/*------------------------------------------------------------------------------------------*
+ * Local functions
+ *------------------------------------------------------------------------------------------*/
+
+static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer(
+ IVAS_REND_AudioBuffer buffer,
+ const int16_t chBeginIdx,
+ const int16_t numChannels )
+{
+ ISAR_POST_REND_ReadOnlyAudioBuffer subBuffer;
+
+ subBuffer.config = buffer.config;
+ subBuffer.config.numChannels = numChannels;
+ subBuffer.data_fx = buffer.data_fx + subBuffer.config.numSamplesPerChannel * chBeginIdx;
+
+ return subBuffer;
+}
+
+
+static int16_t getTotalNumInChannels(
+ ISAR_POST_REND_HANDLE hIsarPostRend,
+ ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] )
+{
+ int16_t totalNumInChannels = 0;
+ int16_t i, numInputChannels;
+ ivas_error error;
+
+ for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
+ {
+ if ( splitBinIds[i] == 0 )
+ {
+ /* Skip inactive inputs */
+ continue;
+ }
+
+ if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ totalNumInChannels += numInputChannels;
+ }
+
+ return totalNumInChannels;
+}
+
+/*------------------------------------------------------------------------------------------*
+ * Local functions
+ *------------------------------------------------------------------------------------------*/
+
+static const CmdLnParser_Option *findOptionById(
+ const int32_t id )
+{
+ for ( int32_t i = 0; i < numCliOptions; ++i )
+ {
+ if ( cliOptions[i].id == id )
+ {
+ return &cliOptions[i];
+ }
+ }
+
+ return NULL;
+}
+
+static bool parseInConfig(
+ const char *inFormatStr,
+ InputConfig *inConfig,
+ bool *sceneDescriptionInput )
+{
+ char charBuf[FILENAME_MAX];
+
+ /* Initialize input config struct */
+ inConfig->numBinBuses = 0;
+
+ /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */
+ strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 );
+ charBuf[sizeof( charBuf ) - 1] = '\0';
+ to_upper( charBuf );
+ if ( strcmp( charBuf, "META" ) == 0 )
+ {
+ *sceneDescriptionInput = true;
+ /* Parsing the file will be done later. At this point the actual file path
+ * may not be known as command line parameters are still being parsed. */
+ return true;
+ }
+
+ /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */
+ IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr );
+ switch ( audioConfig )
+ {
+ case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED:
+ case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM:
+ inConfig->numBinBuses = 1;
+ inConfig->binBuses[0].audioConfig = audioConfig;
+ inConfig->binBuses[0].inputChannelIndex = 0;
+ inConfig->binBuses[0].gain_dB = 0.0f;
+ break;
+ default:
+ {
+ /* Default case covers formats that are defined in the AUDIO_CONFIG enum,
+ * but cannot be used at input, e.g. BINAURAL */
+ const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats );
+ fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+static bool parseRenderFramesize(
+ char *value,
+ IVAS_RENDER_FRAMESIZE *render_framesize )
+{
+ int32_t tmp;
+
+ *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN;
+ if ( !is_digits_only( value ) )
+ {
+ return false;
+ }
+ tmp = (int32_t) strtol( value, NULL, 0 );
+ switch ( (int16_t) tmp )
+ {
+ case 5:
+ *render_framesize = IVAS_RENDER_FRAMESIZE_5MS;
+ break;
+ case 10:
+ *render_framesize = IVAS_RENDER_FRAMESIZE_10MS;
+ break;
+ case 20:
+ *render_framesize = IVAS_RENDER_FRAMESIZE_20MS;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+static IVAS_AUDIO_CONFIG parseAudioConfig(
+ const char *configString )
+{
+ char charBuf[25];
+ charBuf[24] = '\0';
+
+ strncpy( charBuf, configString, sizeof( charBuf ) - 1 );
+ charBuf[sizeof( charBuf ) - 1] = '\0';
+ to_upper( charBuf );
+
+ if ( strcmp( charBuf, "BINAURAL" ) == 0 )
+ {
+ return IVAS_AUDIO_CONFIG_BINAURAL;
+ }
+ if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 )
+ {
+ return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM;
+ }
+ if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 )
+ {
+ return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED;
+ }
+ return IVAS_AUDIO_CONFIG_INVALID;
+}
+
+
+static bool checkRequiredArgs(
+ CmdlnArgs args )
+{
+ const CmdLnParser_Option *tmpOption;
+
+ /* Check required arguments */
+ bool missingRequiredArg = false;
+ if ( isEmptyString( args.inputFilePath ) )
+ {
+ tmpOption = findOptionById( CmdLnOptionId_inputFile );
+ fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
+ missingRequiredArg = true;
+ }
+
+ const bool singleInputSpecified = ( args.inConfig.numBinBuses != 0 );
+
+ if ( !args.sceneDescriptionInput && !singleInputSpecified )
+ {
+ /* Neither scene description input nor single-type input was specified on command line */
+ tmpOption = findOptionById( CmdLnOptionId_inputFormat );
+ fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
+ missingRequiredArg = true;
+ }
+ if ( isEmptyString( args.outputFilePath ) )
+ {
+ tmpOption = findOptionById( CmdLnOptionId_outputFile );
+ fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
+ missingRequiredArg = true;
+ }
+ if ( args.sampleRate == 0 )
+ {
+ tmpOption = findOptionById( CmdLnOptionId_sampleRate );
+ fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
+ missingRequiredArg = true;
+ }
+ if ( missingRequiredArg )
+ {
+ CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions );
+ }
+
+ return !missingRequiredArg;
+}
+
+static CmdlnArgs defaultArgs(
+ const char *executableName )
+{
+ CmdlnArgs args;
+
+ strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH );
+ clearString( args.inputFilePath );
+ clearString( args.outputFilePath );
+ args.sampleRate = 0;
+
+ args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID;
+
+ for ( int32_t i = 0; i < RENDERER_MAX_ISAR_MD_INPUTS; ++i )
+ {
+ clearString( args.inMetadataFilePaths[i] );
+ }
+ args.numInMetadataFiles = 0;
+
+ clearString( args.headRotationFilePath );
+ clearString( args.splitRendBFIFilePath );
+
+ args.delayCompensationEnabled = true;
+ args.quietModeEnabled = false;
+ args.sceneDescriptionInput = false;
+
+ args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS;
+
+ return args;
+}
+
+static void parseOption(
+ const int32_t optionId,
+ char **optionValues,
+ const int16_t numOptionValues,
+ void *pOutputStruct )
+{
+ CmdlnArgs *args = pOutputStruct;
+
+ switch ( optionId )
+ {
+ case CmdLnOptionId_listFormats:
+ assert( numOptionValues == 0 );
+ printSupportedAudioConfigs();
+ exit( 0 );
+ case CmdLnOptionId_inputFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->inputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_inputFormat:
+ assert( numOptionValues == 1 );
+ if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) )
+ {
+ exit( -1 ); /* Error printout handled by failing function */
+ }
+ break;
+ case CmdLnOptionId_inputMetadata:
+ assert( numOptionValues <= RENDERER_MAX_ISAR_MD_INPUTS );
+ for ( int16_t i = 0; i < numOptionValues; ++i )
+ {
+ strncpy( args->inMetadataFilePaths[i], optionValues[i], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
+ }
+ args->numInMetadataFiles = numOptionValues;
+ break;
+ case CmdLnOptionId_outputFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->outputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_sampleRate:
+ assert( numOptionValues == 1 );
+ args->sampleRate = (int32_t) ( strtol( optionValues[0], NULL, 10 ) * 1000 );
+ if ( args->sampleRate == 0 )
+ {
+ fprintf( stderr, "Invalid sampling rate specified\n" );
+ exit( -1 );
+ }
+ break;
+ case CmdLnOptionId_trajFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->headRotationFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_SplitRendBFIFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->splitRendBFIFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_complexityLevel:
+ assert( numOptionValues == 1 );
+ args->complexityLevel = (int32_t) ( strtol( optionValues[0], NULL, 10 ) );
+ if ( args->complexityLevel < ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel > ISAR_POST_REND_COMPLEXITY_LEVEL_THREE )
+ {
+ fprintf( stdout, "Invalid complexity level specified.\n" );
+ exit( -1 );
+ }
+ else if ( args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_TWO )
+ {
+ fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" );
+ }
+ break;
+ case CmdLnOptionId_noDelayCmp:
+ assert( numOptionValues == 0 );
+ args->delayCompensationEnabled = false;
+ break;
+ case CmdLnOptionId_quietModeEnabled:
+ assert( numOptionValues == 0 );
+ args->quietModeEnabled = true;
+ break;
+ case CmdLnOptionId_framing:
+ assert( numOptionValues == 1 );
+ if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) )
+ {
+ fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] );
+ exit( -1 );
+ }
+
+ break;
+ default:
+ assert( 0 && "This should be unreachable - all command line options should be explicitly handled." );
+ break;
+ }
+
+ return;
+}
+
+static CmdlnArgs parseCmdlnArgs(
+ const int argc,
+ char **argv )
+{
+ CmdlnArgs args = defaultArgs( argv[0] );
+
+ if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 )
+ {
+ exit( -1 ); /* Error printout handled by failing function */
+ }
+
+ if ( !checkRequiredArgs( args ) )
+ {
+ exit( -1 ); /* Error printout handled by failing function */
+ }
+
+ return args;
+}
+
+
+static void printSupportedAudioConfigs( void )
+{
+ uint16_t i;
+ const char *supportedFormats[] = {
+ "BINAURAL (output only)",
+ "BINAURAL_SPLIT_PCM",
+ "BINAURAL_SPLIT_CODED",
+ };
+
+ fprintf( stdout, "Supported audio formats:\n" );
+ for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ )
+ {
+ fprintf( stdout, "%s\n", supportedFormats[i] );
+ }
+
+ return;
+}
+
+/*--------------------------------------------------------------------------*
+ * convertInputBuffer()
+ *
+ * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format
+ * accepted by the renderer (float, packed)
+ *--------------------------------------------------------------------------*/
+
+static void convertInputBuffer(
+ const int16_t *intBuffer,
+ const int16_t numIntSamplesPerChannel,
+ const int16_t numFloatSamplesPerChannel,
+ const int16_t numChannels,
+ Word32 *fixedBuffer )
+{
+ int16_t chnl, smpl, i;
+
+ i = 0;
+
+ FOR( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl )
+ {
+ FOR( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ IF( i < numIntSamplesPerChannel )
+ {
+ fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = (Word32) intBuffer[i];
+ }
+ ELSE
+ {
+ fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0;
+ }
+
+ ++i;
+ }
+ }
+
+ return;
+}
+
+/*--------------------------------------------------------------------------*
+ * convertOutputBuffer()
+ *
+ * Convert output buffer from the renderer (float, packed) to a format ready
+ * for writing to a WAV/PCM file (int16_t, interleaved)
+ *--------------------------------------------------------------------------*/
+
+static void convertOutputBuffer(
+ const Word32 *fixedBuffer,
+ Word16 q,
+ const int16_t numSamplesPerChannel,
+ const int16_t numChannels,
+ int16_t *intBuffer )
+{
+ int16_t chnl, smpl, i;
+ Word32 temp;
+
+ i = 0;
+
+ for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl )
+ {
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ temp = L_shr_r( fixedBuffer[chnl * numSamplesPerChannel + smpl], q );
+ IF( GT_32( temp, ISAR_MAX16B_FX ) )
+ {
+ temp = ISAR_MAX16B_FX;
+ }
+ ELSE IF( LT_32( temp, ISAR_MIN16B_FX ) )
+ {
+ temp = ISAR_MIN16B_FX;
+ }
+ intBuffer[i] = (int16_t) temp;
+
+ ++i;
+ }
+ }
+
+ return;
+}
+
+/*------------------------------------------------------------------------------------------*
+ * main()
+ *
+ * Main ISAR post renderer function for command-line interface
+ *------------------------------------------------------------------------------------------*/
+
+int main(
+ int argc,
+ char **argv )
+{
+ ISAR_POST_REND_HANDLE hIsarPostRend;
+ RotFileReader *headRotReader = NULL;
+ RotFileReader *externalOrientationFileReader = NULL;
+ SplitRendBFIFileReader *splitRendBFIReader = NULL;
+ AudioFileReader *audioReader = NULL;
+ AudioFileWriter *audioWriter;
+ int32_t inBufferSize;
+ int32_t outBufferSize;
+ int32_t bitsBufferSize;
+ int16_t *inpInt16Buffer;
+ Word32 *inFloatBuffer_fx;
+ int16_t *outInt16Buffer;
+ Word32 *outFloatBuffer_fx;
+ uint8_t *bitsBufferData = NULL;
+ IVAS_REND_AudioBuffer inBuffer;
+ IVAS_REND_AudioBuffer outBuffer;
+ ISAR_POST_REND_BitstreamBuffer bitsBuffer;
+ SplitFileReadWrite *hSplitRendFileReadWrite;
+ char audioFilePath[FILENAME_MAX];
+ int16_t numSamplesRead;
+ int16_t delayNumSamples = -1;
+ int16_t delayNumSamples_orig = 0;
+ int16_t zeroPad = 0;
+ int16_t zeroPadToWrite = 0;
+ int32_t delayTimeScale = 0;
+ int16_t i, numChannels;
+ ivas_error error = IVAS_ERR_OK;
+ bool splitBinNeedsNewFrame = true;
+
+#ifdef WMOPS
+ reset_wmops();
+ reset_mem( USE_BYTES );
+#endif
+
+ hSplitRendFileReadWrite = NULL;
+ bitsBuffer.bits = NULL;
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+ bitsBuffer.config.bufLenInBytes = 0;
+ bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
+ bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ bitsBuffer.config.codec_frame_size_ms = 5;
+ bitsBuffer.config.isar_frame_size_ms = 20;
+ bitsBuffer.config.lc3plusHighRes = 0;
+#else
+ bitsBuffer.config.codec_frame_size_ms = 20;
+#endif
+
+
+ CmdlnArgs args = parseCmdlnArgs( argc, argv );
+
+ convert_backslash( args.inputFilePath );
+ convert_backslash( args.outputFilePath );
+ convert_backslash( args.headRotationFilePath );
+
+ if ( !isEmptyString( args.headRotationFilePath ) )
+ {
+ if ( RotationFileReader_open( args.headRotationFilePath, &headRotReader ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening file: %s\n", args.headRotationFilePath );
+ exit( -1 );
+ }
+ }
+
+ if ( !isEmptyString( args.splitRendBFIFilePath ) )
+ {
+ convert_backslash( args.splitRendBFIFilePath );
+ SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t inFileSampleRate = 0;
+#endif
+ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 );
+ hSplitRendFileReadWrite = NULL;
+ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ error = split_rend_reader_open( &hSplitRendFileReadWrite,
+ args.inMetadataFilePaths[0],
+ &bitsBuffer.config.codec,
+ &bitsBuffer.config.poseCorrection,
+ &bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ &bitsBuffer.config.isar_frame_size_ms,
+ &inFileSampleRate,
+ &bitsBuffer.config.lc3plusHighRes
+#endif
+ );
+ if ( error != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] );
+ exit( -1 );
+ }
+
+ if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening file: %s\n", audioFilePath );
+ exit( -1 );
+ }
+ }
+
+ /*if split renderer is running in post renderer mode*/
+ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) )
+ {
+ error = split_rend_reader_open( &hSplitRendFileReadWrite,
+ args.inputFilePath,
+ &bitsBuffer.config.codec,
+ &bitsBuffer.config.poseCorrection,
+ &bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ &bitsBuffer.config.isar_frame_size_ms,
+ &inFileSampleRate,
+ &bitsBuffer.config.lc3plusHighRes
+#endif
+ );
+ if ( error != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath );
+ exit( -1 );
+ }
+ audioReader = NULL;
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t inFileSampleRate = 0;
+#endif
+ if ( audioReader != NULL )
+ {
+ error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate );
+ }
+ else
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( hSplitRendFileReadWrite == NULL )
+#endif
+ {
+ inFileSampleRate = args.sampleRate;
+ }
+
+ switch ( error )
+ {
+ case IVAS_ERR_OK:
+ /* If sampling rate not given on command line, use the one from SR file */
+ if ( args.sampleRate == 0 )
+ {
+ args.sampleRate = inFileSampleRate;
+ }
+ /* else if sampling rate given on command line, compare with wav file */
+ else if ( inFileSampleRate != args.sampleRate )
+ {
+ fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath );
+ exit( -1 );
+ }
+ break;
+ case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */
+ if ( args.sampleRate == 0 )
+ {
+ fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" );
+ exit( -1 );
+ }
+ break;
+ default:
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ int16_t inFileNumChannels = 0;
+ if ( audioReader != NULL )
+ {
+ error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels );
+ if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) );
+ args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL;
+ if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ /* === Configure === */
+ if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in Renderer Config Init: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ if ( args.inConfig.numBinBuses > 0 )
+ {
+ if ( ( error = ISAR_REND_SetSplitRendBitstreamHeader( hIsarPostRend,
+ bitsBuffer.config.codec,
+ bitsBuffer.config.poseCorrection,
+ bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ bitsBuffer.config.isar_frame_size_ms,
+ bitsBuffer.config.lc3plusHighRes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in getting split renderer bitstream header: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+
+
+ ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS];
+
+ for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ )
+ {
+ splitBinIds[i] = 0u;
+ }
+
+ for ( i = 0; i < args.inConfig.numBinBuses; ++i )
+ {
+ if ( ( error = ISAR_POST_REND_AddInput( hIsarPostRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+
+ const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds );
+
+ if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels )
+ {
+ fprintf( stderr, "Number of channels in input file does not match selected configuration\n" );
+ exit( -1 );
+ }
+
+ int16_t numOutChannels = 2;
+
+ if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath );
+ exit( -1 );
+ }
+
+ inBufferSize = frameSize_smpls * totalNumInChannels;
+ outBufferSize = frameSize_smpls * numOutChannels;
+ inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) );
+ memset( inpInt16Buffer, 0, inBufferSize * sizeof( int16_t ) );
+
+ inFloatBuffer_fx = malloc( inBufferSize * sizeof( Word32 ) );
+ inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
+ outFloatBuffer_fx = malloc( outBufferSize * sizeof( Word32 ) );
+ outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
+
+ outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) );
+
+ inBuffer.config.is_cldfb = 0;
+ inBuffer.config.numChannels = (int16_t) totalNumInChannels;
+ inBuffer.data_fx = inFloatBuffer_fx;
+ inBuffer.q_data_fx = malloc( sizeof( Word16 ) );
+
+ outBuffer.config.is_cldfb = 0;
+ outBuffer.config.numChannels = (int16_t) numOutChannels;
+ outBuffer.data_fx = outFloatBuffer_fx;
+ outBuffer.q_data_fx = malloc( sizeof( Word16 ) );
+
+ memset( outBuffer.data_fx, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( Word32 ) );
+
+ bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE;
+
+ if ( bitsBufferSize > 0 )
+ {
+ bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) );
+ }
+ else
+ {
+ bitsBufferData = NULL;
+ }
+
+ bitsBuffer.bits = bitsBufferData;
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+ bitsBuffer.config.bufLenInBytes = bitsBufferSize;
+
+#ifdef WMOPS
+ reset_stack();
+ reset_wmops();
+#endif
+
+ if ( !args.quietModeEnabled )
+ {
+ fprintf( stdout, "\n------ Running the ISAR post renderer ------\n\n" );
+ fprintf( stdout, "Frames processed: " );
+ }
+ else
+ {
+ fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" );
+ }
+
+ while ( 1 )
+ {
+ int16_t num_in_channels;
+ num_in_channels = inBuffer.config.numChannels;
+
+ numSamplesRead = 0;
+ if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame )
+ {
+ ivas_error error_tmp;
+ numSamplesRead = (int16_t) inBufferSize;
+ error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten );
+ if ( error_tmp != IVAS_ERR_OK )
+ {
+ if ( error_tmp == IVAS_ERR_END_OF_FILE )
+ {
+ numSamplesRead = 0;
+ }
+ else
+ {
+ fprintf( stderr, "\nUnable to read from bitstream file!\n" );
+ exit( -1 );
+ }
+ }
+ }
+
+ if ( audioReader != NULL )
+ {
+ /* Read the input data */
+ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError reading from file %s\n", audioFilePath );
+ exit( -1 );
+ }
+ }
+
+ if ( numSamplesRead == 0 && splitBinNeedsNewFrame )
+ {
+ /* end of input data */
+ break;
+ }
+
+ /* Convert from int to float and from interleaved to packed */
+ convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer_fx );
+ *inBuffer.q_data_fx = 0;
+ int16_t num_subframes, sf_idx;
+ num_subframes = (int16_t) args.render_framesize;
+
+ /* Read from head rotation trajectory file if specified */
+ if ( headRotReader != NULL )
+ {
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IVAS_QUATERNION headRot;
+ IVAS_VECTOR3 Pos;
+
+ IF( ( error = HeadRotationFileReading_fx( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ if ( ( error = ISAR_POST_REND_SetHeadRotation( hIsarPostRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ }
+ else
+ {
+ fprintf( stderr, "Head Rotation should be enabled in post renderer\n" );
+ exit( -1 );
+ }
+
+ /* Read from split renderer bfi file if specified */
+ if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame )
+ {
+ int16_t bfi;
+ if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+
+ for ( i = 0; i < args.inConfig.numBinBuses; ++i )
+ {
+ if ( numSamplesRead > 0 )
+ {
+ if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ ISAR_POST_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels );
+
+ if ( ( error = ISAR_POST_REND_FeedInputAudio( hIsarPostRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ if ( splitBinNeedsNewFrame )
+ {
+ if ( ( error = ISAR_POST_REND_FeedSplitBinauralBitstream( hIsarPostRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ }
+
+ if ( ( error = ISAR_POST_REND_GetSplitBinauralSamples( hIsarPostRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+
+ int16_t num_out_channels;
+ num_out_channels = outBuffer.config.numChannels;
+
+ /* Convert from float to int and from packed to interleaved.
+ * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */
+ convertOutputBuffer( outFloatBuffer_fx, *outBuffer.q_data_fx, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer );
+
+ if ( delayNumSamples == -1 )
+ {
+ if ( args.delayCompensationEnabled )
+ {
+ if ( ISAR_POST_REND_GetDelay( hIsarPostRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to get delay of renderer!\n" );
+ exit( -1 );
+ }
+
+ if ( hSplitRendFileReadWrite != NULL )
+ {
+ uint32_t pre_rend_delay_ns;
+ split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns );
+ delayNumSamples += (Word16) ( ( ( (Word64) pre_rend_delay_ns * delayTimeScale ) + 500000000 ) / 1000000000 );
+ }
+
+ delayNumSamples_orig = delayNumSamples;
+ }
+ else
+ {
+ delayNumSamples = 0;
+ }
+ zeroPad = delayNumSamples;
+ }
+
+ if ( audioWriter != NULL )
+ {
+ if ( delayNumSamples * num_out_channels < outBufferSize )
+ {
+ if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath );
+ exit( -1 );
+ }
+ delayNumSamples = 0;
+ }
+ else
+ {
+ delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels );
+ }
+ }
+
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+
+ frame++;
+ if ( !args.quietModeEnabled )
+ {
+ fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame );
+ }
+
+#ifdef WMOPS
+ update_mem();
+ update_wmops();
+#endif
+ }
+
+ /* add zeros at the end to have equal length of synthesized signals */
+ if ( audioWriter != NULL )
+ {
+ for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls )
+ {
+ memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) );
+ if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nOutput audio file writer error\n" );
+ exit( -1 );
+ }
+ }
+
+ memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) );
+ if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nOutput audio file writer error\n" );
+ exit( -1 );
+ }
+ zeroPadToWrite = 0;
+ }
+
+ if ( !args.quietModeEnabled && args.delayCompensationEnabled )
+ {
+ fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale );
+ }
+
+ fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame );
+
+#ifdef DEBUGGING
+ int32_t cnt_frames_limited, noClipping;
+ if ( ( cnt_frames_limited = ISAR_POST_REND_GetCntFramesLimited( hIsarPostRend ) ) > 0 )
+ {
+ fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited );
+ }
+ if ( ( noClipping = ISAR_POST_REND_GetNoCLipping( hIsarPostRend ) ) > 0 )
+ {
+ fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping );
+ }
+#endif
+
+ /* === Close === */
+ free( inpInt16Buffer );
+ free( inFloatBuffer_fx );
+ free( inBuffer.q_data_fx );
+ free( outInt16Buffer );
+ free( outFloatBuffer_fx );
+ free( outBuffer.q_data_fx );
+
+ if ( bitsBufferData != NULL )
+ {
+ free( bitsBufferData );
+ }
+
+ split_rend_reader_writer_close( &hSplitRendFileReadWrite );
+ SplitRendBFIFileReader_close( &splitRendBFIReader );
+
+ AudioFileReader_close( &audioReader );
+ AudioFileWriter_close( &audioWriter );
+ RotationFileReader_close( &headRotReader );
+ RotationFileReader_close( &externalOrientationFileReader );
+
+ ISAR_POST_REND_Close( &hIsarPostRend );
+
+#ifdef DEBUGGING
+ dbgclose();
+#endif
+#ifdef WMOPS
+ print_wmops();
+ print_mem( NULL );
+#endif
+
+ return 0;
+}
+
+
+#undef WMC_TOOL_SKIP
+
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
diff --git a/apps/renderer.c b/apps/renderer.c
index f5c0a8847264b45944f245818f8a7b332efd9d0a..9b64aff936f84d85faf71dbec9d2f45831dcaadb 100644
--- a/apps/renderer.c
+++ b/apps/renderer.c
@@ -45,6 +45,10 @@
#include "masa_file_writer.h"
#include "render_config_reader.h"
#include "rotation_file_reader.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "split_render_file_read_write.h"
+#include "split_rend_bfi_file_reader.h"
+#endif
#include "vector3_pair_file_reader.h"
#include "wmc_auto.h"
@@ -148,7 +152,13 @@ typedef struct
OutputConfig outConfig;
char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH];
int16_t numInMetadataFiles;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+#endif
char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
+#endif
char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
@@ -195,6 +205,10 @@ typedef enum
CmdLnOptionId_inputMetadata,
CmdLnOptionId_listFormats,
CmdLnOptionId_inputGain,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ CmdLnOptionId_outputMetadata,
+ CmdLnOptionId_SplitRendBFIFile,
+#endif
CmdLnOptionId_referenceVectorFile,
CmdLnOptionId_exteriorOrientationFile,
CmdLnOptionId_framing,
@@ -220,7 +234,11 @@ static const CmdLnParser_Option cliOptions[] = {
.id = CmdLnOptionId_inputMetadata,
.match = "input_metadata",
.matchShort = "im",
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode",
+#else
.description = "Space-separated list of path to metadata files for ISM or MASA inputs",
+#endif
},
{
.id = CmdLnOptionId_outputFile,
@@ -246,6 +264,20 @@ static const CmdLnParser_Option cliOptions[] = {
.matchShort = "T",
.description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)",
},
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ {
+ .id = CmdLnOptionId_outputMetadata,
+ .match = "output_metadata",
+ .matchShort = "om",
+ .description = "coded metadata file for BINAURAL_SPLIT_PCM output mode",
+ },
+ {
+ .id = CmdLnOptionId_SplitRendBFIFile,
+ .match = "post_rend_bfi_file",
+ .matchShort = "prbfi",
+ .description = "Split rendering option: bfi file",
+ },
+#endif
{
.id = CmdLnOptionId_refRotFile,
.match = "reference_rotation_file",
@@ -403,11 +435,19 @@ static void printSupportedAudioConfigs( void );
static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna );
+
+static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn );
+static void convertOutputBuffer_fx( const Word32 *Word32Buffer, const Word16 numSamplesPerChannel, const Word16 numChannels, Word16 *intBuffer, Word16 q_factor, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn );
+static void convertInputBuffer_fx( const Word16 *intBuffer, const Word16 numIntSamplesPerChannel, const Word16 numFloatSamplesPerChannel, const Word16 numChannels, Word32 *Int32Buffer, Word16 in_q_factor, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna );
+#else
static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer );
static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer );
static void convertOutputBuffer_fx( const Word32 *Word32Buffer, const Word16 numSamplesPerChannel, const Word16 numChannels, Word16 *intBuffer, Word16 q_factor );
static void convertInputBuffer_fx( const Word16 *intBuffer, const Word16 numIntSamplesPerChannel, const Word16 numFloatSamplesPerChannel, const Word16 numChannels, Word32 *Int32Buffer, Word16 in_q_factor );
+#endif
/*------------------------------------------------------------------------------------------*
@@ -593,6 +633,44 @@ static float dBToLin(
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+static int16_t get_cldfb_in_flag(
+ const IVAS_AUDIO_CONFIG audioConfig,
+ const IVAS_RENDER_CONFIG_DATA *renderConfig )
+{
+ int16_t cldfb_in_flag;
+
+ cldfb_in_flag = 0;
+ if ( renderConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
+ {
+#ifdef DEBUGGING
+ cldfb_in_flag = 1;
+#endif
+ if ( audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
+ {
+ cldfb_in_flag = 1;
+ }
+ }
+
+ return cldfb_in_flag;
+}
+
+static int16_t is_split_pre_rend_mode(
+ CmdlnArgs *args )
+{
+ int16_t flag;
+
+ flag = 0;
+ if ( args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ flag = 1;
+ }
+
+ return flag;
+}
+#endif
+
+
/*------------------------------------------------------------------------------------------*
* main()
*
@@ -607,6 +685,12 @@ int main(
RotFileReader *headRotReader = NULL;
RotFileReader *externalOrientationFileReader = NULL;
RotFileReader *referenceRotReader = NULL;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS];
+ IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS];
+ int16_t cldfb_in_flag, CLDFBframeSize_smpls;
+ SplitRendBFIFileReader *splitRendBFIReader = NULL;
+#endif
Vector3PairFileReader *referenceVectorReader = NULL;
hrtfFileReader *hrtfFileReader = NULL;
IsmPositionProvider *positionProvider;
@@ -620,6 +704,9 @@ int main(
AudioFileWriter *audioWriter;
int32_t inBufferSize;
int32_t outBufferSize;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ int32_t bitsBufferSize;
+#endif
int16_t *inpInt16Buffer;
float *inFloatBuffer;
int16_t *outInt16Buffer;
@@ -627,8 +714,17 @@ int main(
Word32 *inInt32Buffer;
Word32 gain_fx;
float *outFloatBuffer;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ uint8_t *bitsBufferData = NULL;
+#endif
IVAS_REND_AudioBuffer inBuffer;
IVAS_REND_AudioBuffer outBuffer;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IVAS_REND_BitstreamBuffer bitsBuffer;
+ SplitFileReadWrite *hSplitRendFileReadWrite;
+ int16_t delayNumSamples_temp;
+ int32_t delayTimeScale_temp;
+#endif
int16_t numSamplesRead;
int16_t delayNumSamples = -1;
int16_t delayNumSamples_orig = 0;
@@ -637,7 +733,6 @@ int main(
int32_t delayTimeScale = 0;
int16_t i, numChannels;
ivas_error error = IVAS_ERR_OK;
- bool splitBinNeedsNewFrame = true;
#ifdef WMOPS
reset_wmops();
@@ -650,6 +745,24 @@ int main(
hMasaMetadata[i] = NULL;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ hSplitRendFileReadWrite = NULL;
+ CLDFBframeSize_smpls = 0;
+ cldfb_in_flag = 0;
+ bitsBuffer.bits = NULL;
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+ bitsBuffer.config.bufLenInBytes = 0;
+ bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
+ bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ bitsBuffer.config.codec_frame_size_ms = 5;
+ bitsBuffer.config.isar_frame_size_ms = 20;
+ bitsBuffer.config.lc3plus_highres = 0;
+#else
+ bitsBuffer.config.codec_frame_size_ms = 20;
+#endif
+#endif
for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i )
{
lfeRoutingConfigs[i] = NULL;
@@ -710,6 +823,13 @@ int main(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( !isEmptyString( args.splitRendBFIFilePath ) )
+ {
+ convert_backslash( args.splitRendBFIFilePath );
+ SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader );
+ }
+#endif
if ( !isEmptyString( args.externalOrientationFilePath ) )
{
if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK )
@@ -877,16 +997,28 @@ int main(
IVAS_RENDER_CONFIG_DATA renderConfig;
/* sanity check */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) )
+ {
+ fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" );
+ exit( -1 );
+ }
+#else
if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
{
fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" );
exit( -1 );
}
+#endif
if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) );
+#else
fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" );
+#endif
exit( -1 );
}
@@ -914,11 +1046,28 @@ int main(
renderConfig.roomAcoustics.override = 1;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /* ISAR frame size is set from command line, not renderer config file.
+ * This will be ignored if output format is not split rendering. */
+ renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) args.render_framesize /* given in number of 5ms subframes */ * 5;
+#endif
+#endif
+
if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) );
+#else
fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" );
+#endif
exit( -1 );
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ CLDFBframeSize_smpls = frameSize_smpls * 2;
+ cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig );
+#endif
}
if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK )
@@ -1173,17 +1322,160 @@ int main(
exit( -1 );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( cldfb_in_flag )
+ {
+ if ( ( error = IVAS_REND_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in IVAS_REND_openCldfb(): %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+
+ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
+ {
+
+ IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend,
+ &bitsBuffer.config.codec,
+ &bitsBuffer.config.poseCorrection,
+ &bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ &bitsBuffer.config.isar_frame_size_ms
+#endif
+ );
+
+ if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to get delay of renderer!\n" );
+ exit( -1 );
+ }
+
+ if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite,
+ args.outputFilePath,
+ delayNumSamples_temp,
+ delayTimeScale_temp,
+ bitsBuffer.config.codec,
+ bitsBuffer.config.poseCorrection,
+ bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ bitsBuffer.config.isar_frame_size_ms,
+ args.sampleRate,
+ bitsBuffer.config.lc3plus_highres
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath );
+ exit( -1 );
+ }
+ audioWriter = NULL;
+ }
+ else
+ {
+ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+
+ IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend,
+ &bitsBuffer.config.codec,
+ &bitsBuffer.config.poseCorrection,
+ &bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ &bitsBuffer.config.isar_frame_size_ms
+#endif
+ );
+
+ if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to get delay of renderer!\n" );
+ exit( -1 );
+ }
+
+ if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite,
+ args.outMetadataFilePath,
+ delayNumSamples_temp,
+ delayTimeScale_temp,
+ bitsBuffer.config.codec,
+ bitsBuffer.config.poseCorrection,
+ bitsBuffer.config.codec_frame_size_ms
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ bitsBuffer.config.isar_frame_size_ms,
+ args.sampleRate,
+ bitsBuffer.config.lc3plus_highres
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath );
+ exit( -1 );
+ }
+ }
+#endif
if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK )
{
fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath );
exit( -1 );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
inBufferSize = frameSize_smpls * totalNumInChannels;
outBufferSize = frameSize_smpls * numOutChannels;
inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( cldfb_in_flag == 0 )
+ {
+ inFloatBuffer = malloc( inBufferSize * sizeof( float ) );
+ inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
+ outFloatBuffer = malloc( outBufferSize * sizeof( float ) );
+ outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
+ }
+ else
+ {
+ inFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) );
+ inBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls;
+ outFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) );
+ outBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls;
+ }
+ outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) );
+
+ inBuffer.config.is_cldfb = cldfb_in_flag;
+ inBuffer.config.numChannels = (int16_t) totalNumInChannels;
+ inBuffer.data = inFloatBuffer;
+
+ outBuffer.config.is_cldfb = cldfb_in_flag;
+ outBuffer.config.numChannels = (int16_t) numOutChannels;
+ outBuffer.data = outFloatBuffer;
+
+ memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) );
+
+ if ( is_split_pre_rend_mode( &args ) )
+ {
+ bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE;
+ }
+ else
+ {
+ bitsBufferSize = 0;
+ }
+
+ if ( bitsBufferSize > 0 )
+ {
+ bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) );
+ }
+ else
+ {
+ bitsBufferData = NULL;
+ }
+
+ bitsBuffer.bits = bitsBufferData;
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+ bitsBuffer.config.bufLenInBytes = bitsBufferSize;
+#else
inFloatBuffer = malloc( inBufferSize * sizeof( float ) );
outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) );
outInt32Buffer = malloc( outBufferSize * sizeof( Word32 ) );
@@ -1197,6 +1489,8 @@ int main(
outBuffer.config.numChannels = (int16_t) numOutChannels;
outBuffer.data_fx = outInt32Buffer;
inBuffer.data_fx = inInt32Buffer;
+#endif
+
#ifdef WMOPS
reset_stack();
reset_wmops();
@@ -1222,6 +1516,8 @@ int main(
num_in_channels = inBuffer.config.numChannels;
const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0;
+ numSamplesRead = 0;
+
/* Read the input data */
if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK )
{
@@ -1229,14 +1525,18 @@ int main(
exit( -1 );
}
- if ( numSamplesRead == 0 && splitBinNeedsNewFrame )
+ if ( numSamplesRead == 0 )
{
/* end of input data */
break;
}
/* Convert from int to float and from interleaved to packed */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer, inBuffer.config.is_cldfb, cldfbAna );
+#else
convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer );
+#endif
*outBuffer.pq_fact = 16 - ( gd_bits );
convertInputBuffer_fx( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inInt32Buffer, *outBuffer.pq_fact );
int16_t num_subframes, sf_idx;
@@ -1295,7 +1595,11 @@ int main(
exit( -1 );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK )
+#endif
{
fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) );
exit( -1 );
@@ -1448,19 +1752,43 @@ int main(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ if ( ( error = IVAS_REND_GetSplitBinauralBitstream( hIvasRend, outBuffer, &bitsBuffer ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
+ exit( -1 );
+ }
+ }
+ else
+ {
+#endif
if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) );
+#else
fprintf( stderr, "Error in getting samples\n" );
+#endif
exit( -1 );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
int16_t num_out_channels;
num_out_channels = outBuffer.config.numChannels;
+
/* Convert from float to int and from packed to interleaved.
* Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */
if ( *outBuffer.pq_fact == 0 )
{
- convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer );
+ #ifdef SPLIT_REND_WITH_HEAD_ROT
+ convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, cldfb_in_flag, cldfbSyn );
+#else
+ convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer );
+#endif
}
else
{
@@ -1486,6 +1814,20 @@ int main(
zeroPad = delayNumSamples;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( is_split_pre_rend_mode( &args ) )
+ {
+ if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead,
+ &bitsBuffer.config.bitsWritten ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nUnable to write to bitstream file!\n" );
+ exit( -1 );
+ }
+ }
+
+ if ( audioWriter != NULL )
+ {
+#endif
if ( delayNumSamples * num_out_channels < outBufferSize )
{
if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK )
@@ -1500,6 +1842,14 @@ int main(
delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+
+ bitsBuffer.config.bitsRead = 0;
+ bitsBuffer.config.bitsWritten = 0;
+#endif
+
+
/* Write MASA metadata for MASA outputs */
if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 )
{
@@ -1603,6 +1953,10 @@ int main(
}
/* add zeros at the end to have equal length of synthesized signals */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( audioWriter != NULL )
+ {
+#endif
for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls )
{
memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) );
@@ -1620,6 +1974,9 @@ int main(
exit( -1 );
}
zeroPadToWrite = 0;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
@@ -1642,11 +1999,27 @@ int main(
free( outFloatBuffer );
free( outInt32Buffer );
free( inInt32Buffer );
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( bitsBufferData != NULL )
+ {
+ free( bitsBufferData );
+ }
+#endif
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i )
{
MasaFileReader_close( &masaReaders[i] );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( cldfb_in_flag )
+ {
+ IVAS_REND_closeCldfb( cldfbAna, cldfbSyn );
+ }
+
+ split_rend_reader_writer_close( &hSplitRendFileReadWrite );
+ SplitRendBFIFileReader_close( &splitRendBFIReader );
+#endif
for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i )
{
@@ -1946,8 +2319,13 @@ static bool parseOrientationTracking(
static IVAS_AUDIO_CONFIG parseAudioConfig(
const char *configString )
{
+#ifndef SPLIT_REND_WITH_HEAD_ROT
char charBuf[21];
charBuf[20] = '\0';
+#else
+ char charBuf[25];
+ charBuf[24] = '\0';
+#endif
strncpy( charBuf, configString, sizeof( charBuf ) - 1 );
charBuf[sizeof( charBuf ) - 1] = '\0';
@@ -2022,6 +2400,16 @@ static IVAS_AUDIO_CONFIG parseAudioConfig(
{
return IVAS_AUDIO_CONFIG_BINAURAL;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 )
+ {
+ return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM;
+ }
+ if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 )
+ {
+ return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED;
+ }
+#endif
if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 )
{
return IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR;
@@ -2154,6 +2542,10 @@ static CmdlnArgs defaultArgs(
args.numInMetadataFiles = 0;
clearString( args.headRotationFilePath );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ clearString( args.outMetadataFilePath );
+ clearString( args.splitRendBFIFilePath );
+#endif
clearString( args.referenceVectorFilePath );
clearString( args.referenceRotationFilePath );
clearString( args.customHrtfFilePath );
@@ -2246,6 +2638,16 @@ static void parseOption(
assert( numOptionValues == 1 );
strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ case CmdLnOptionId_outputMetadata:
+ assert( numOptionValues == 1 );
+ strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+ case CmdLnOptionId_SplitRendBFIFile:
+ assert( numOptionValues == 1 );
+ strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
+ break;
+#endif
case CmdLnOptionId_referenceVectorFile:
assert( numOptionValues == 1 );
strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
@@ -3264,6 +3666,10 @@ static void printSupportedAudioConfigs( void )
"ISMx (input only)",
"MASAx",
"BINAURAL (output only)",
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ "BINAURAL_SPLIT_PCM",
+ "BINAURAL_SPLIT_CODED",
+#endif
"BINAURAL_ROOM_IR (output only)",
"BINAURAL_ROOM_REVERB (output only)",
};
@@ -3359,29 +3765,81 @@ static void convertInputBuffer(
const int16_t numIntSamplesPerChannel,
const int16_t numFloatSamplesPerChannel,
const int16_t numChannels,
- float *floatBuffer )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ float *floatBuffer,
+ const int16_t cldfb_in_flag,
+ IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna
+#else
+ float *floatBuffer
+#endif
+)
{
int16_t chnl, smpl, i;
i = 0;
- for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( cldfb_in_flag )
+ {
+ int16_t slotIdx, numCldfbBands, numFloatPcmSamples;
+ float fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE];
+
+ numFloatPcmSamples = numFloatSamplesPerChannel >> 1;
+ numCldfbBands = numFloatPcmSamples / IVAS_CLDFB_NO_COL_MAX;
+
+ /* CLDFB Analysis*/
+ assert( numIntSamplesPerChannel <= IVAS_MAX_OUTPUT_CHANNELS * IVAS_MAX_FRAME_SIZE );
+ for ( smpl = 0; smpl < numFloatPcmSamples; ++smpl )
{
for ( chnl = 0; chnl < numChannels; ++chnl )
{
if ( i < numIntSamplesPerChannel )
{
- floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i];
+ fIn[chnl][smpl] = (float) intBuffer[i];
}
else
{
- floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f;
+ fIn[chnl][smpl] = 0.f;
}
++i;
}
}
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ )
+ {
+ IVAS_REND_cldfbAnalysis_ts_wrapper( &fIn[chnl][numCldfbBands * slotIdx],
+ &floatBuffer[( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )],
+ &floatBuffer[numCldfbBands + ( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )],
+ numCldfbBands, cldfbAna[chnl] );
+ }
+ }
+ }
+ else
+ {
+#endif
+ for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl )
+ {
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ if ( i < numIntSamplesPerChannel )
+ {
+ floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i];
+ }
+ else
+ {
+ floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f;
+ }
+
+ ++i;
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
+
return;
}
@@ -3469,36 +3927,97 @@ static void convertOutputBuffer_fx(
* Convert output buffer from the renderer (float, packed) to a format ready
* for writing to a WAV/PCM file (int16_t, interleaved)
*--------------------------------------------------------------------------*/
+
static void convertOutputBuffer(
const float *floatBuffer,
const int16_t numSamplesPerChannel,
const int16_t numChannels,
- int16_t *intBuffer )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ int16_t *intBuffer,
+ const int16_t cldfb_in_flag,
+ IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn
+#else
+ int16_t *intBuffer
+#endif
+)
{
int16_t chnl, smpl, i;
float temp;
i = 0;
- for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( cldfb_in_flag )
{
+ int16_t slotIdx, numCldfbBands, numPcmSamples, b;
+ float fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE];
+ float re[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX];
+ float im[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX];
+
+ numPcmSamples = numSamplesPerChannel >> 1;
+ numCldfbBands = numPcmSamples / IVAS_CLDFB_NO_COL_MAX;
+
+ /* CLDFB Synthesis*/
for ( chnl = 0; chnl < numChannels; ++chnl )
{
- temp = floatBuffer[chnl * numSamplesPerChannel + smpl];
- temp = (float) floor( temp + 0.5f );
- if ( temp > IVAS_MAX16B_FLT )
+ for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ )
{
- temp = IVAS_MAX16B_FLT;
+ for ( b = 0; b < numCldfbBands; b++ )
+ {
+ re[chnl][slotIdx][b] = floatBuffer[( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b];
+ im[chnl][slotIdx][b] = floatBuffer[numCldfbBands + ( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b];
+ }
}
- else if ( temp < IVAS_MIN16B_FLT )
+ }
+
+ /* Implement CLDFB synthesis */
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ float *RealBuffer[IVAS_CLDFB_NO_COL_MAX];
+ float *ImagBuffer[IVAS_CLDFB_NO_COL_MAX];
+
+ for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ )
{
- temp = IVAS_MIN16B_FLT;
+ RealBuffer[slotIdx] = re[chnl][slotIdx];
+ ImagBuffer[slotIdx] = im[chnl][slotIdx];
}
- intBuffer[i] = (int16_t) temp;
- ++i;
+ IVAS_REND_cldfbSynthesis_wrapper( RealBuffer, ImagBuffer, &( fIn[chnl][0] ), numCldfbBands * IVAS_CLDFB_NO_COL_MAX, cldfbSyn[chnl] );
+ }
+ for ( smpl = 0; smpl < numPcmSamples; ++smpl )
+ {
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ intBuffer[i] = (int16_t) roundf( fIn[chnl][smpl] );
+ ++i;
+ }
}
}
+ else
+ {
+#endif
+ for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl )
+ {
+ for ( chnl = 0; chnl < numChannels; ++chnl )
+ {
+ temp = floatBuffer[chnl * numSamplesPerChannel + smpl];
+ temp = (float) floor( temp + 0.5f );
+ if ( temp > IVAS_MAX16B_FLT )
+ {
+ temp = IVAS_MAX16B_FLT;
+ }
+ else if ( temp < IVAS_MIN16B_FLT )
+ {
+ temp = IVAS_MIN16B_FLT;
+ }
+ intBuffer[i] = (int16_t) temp;
+
+ ++i;
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
return;
}
diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c
index 5a3d2e1a27b1fd60aba746579f8bc5cee346fe1e..fe3ed88ea67035c2c9dfb73f9748feb17c0dba06 100644
--- a/lib_com/cldfb.c
+++ b/lib_com/cldfb.c
@@ -61,7 +61,6 @@ static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs );
static void cldfb_init_proto_and_twiddles_enc_fx( HANDLE_CLDFB_FILTER_BANK hs );
-
/*-------------------------------------------------------------------*
* cplxMult()
*
diff --git a/lib_com/cnst.h b/lib_com/cnst.h
index fe16db670a45815e431324c572e699d454512c4a..6cfa7ea4197e600dd16e863a7d958e7d95676037 100644
--- a/lib_com/cnst.h
+++ b/lib_com/cnst.h
@@ -173,6 +173,7 @@
#define MIN16B_FLT_FX_IN_Q15 -1073741824//Q15
#define PCM16_TO_FLT_FAC 32768.0f
#define PCM16_TO_FLT_FAC_FX 32768 //Q0
+#define PCM16_TO_FLT_FAC_FX_Q15 1073741824L //16Q15
#define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC )
#define MDFT_NORM_SCALING_FX 65536 //Q31
#define LOG2_MDFT_NORM_SCALING_FX -503316448 //Q25
@@ -3042,6 +3043,8 @@ enum
#define EVS_2PI_FX_Q27 843314856 /* 2 * pi in Q28 */
#define EVS_PI_BY_2_FX (Word16)(0x3244) // Q13
//#define EVS_PI_FX (Word16)(0x6488)
+#define EVS_PI_FX16 (Word16)(0x6488)
+#define PI2_FX 1686629713 //Q28
#define LG10 24660 /* 10*log10(2) in Q13 */
diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h
index b98f2e7d177c5b2965d400febaaa63732e89341a..894b940b7893dc7902e5ac90dc57076e4f98cdf8 100644
--- a/lib_com/common_api_types.h
+++ b/lib_com/common_api_types.h
@@ -59,6 +59,12 @@
#define IVAS_MAX_PARAM_SPATIAL_SUBFRAMES 4
#define IVAS_ROOM_ABS_COEFF 6
+/* Maximum buffer length (per channel) in samples */
+#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k )
+
+/* Frame size required when rendering to binaural */
+#define BINAURAL_RENDERING_FRAME_SIZE_MS 5
+
/*----------------------------------------------------------------------------------*
* Common API enum for output audio configurations
*----------------------------------------------------------------------------------*/
@@ -210,10 +216,109 @@ typedef struct _IVAS_JBM_TRACE_DATA
} IVAS_JBM_TRACE_DATA;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*----------------------------------------------------------------------------------*
+ * Split rendering API constants, structures, and enums
+ *----------------------------------------------------------------------------------*/
+
+#define ISAR_MAX_SPLIT_REND_BITRATE 768000
+#define ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) ISAR_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 )
+#define ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1
+#define SPLIT_REND_BITS_BUFF_SIZE ( ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES + ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ )
+
+typedef enum
+{
+ DEFAULT_AXIS,
+ YAW,
+ PITCH,
+ ROLL,
+ YAW_PITCH,
+ YAW_ROLL,
+ PITCH_ROLL
+
+} ISAR_SPLIT_REND_ROT_AXIS;
+
+typedef enum
+{
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE,
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB,
+
+} ISAR_SPLIT_REND_POSE_CORRECTION_MODE;
+
+typedef enum
+{
+ ISAR_SPLIT_REND_CODEC_LCLD,
+ ISAR_SPLIT_REND_CODEC_LC3PLUS,
+ ISAR_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */
+ ISAR_SPLIT_REND_CODEC_NONE
+
+} ISAR_SPLIT_REND_CODEC;
+
+typedef enum
+{
+ ISAR_SPLIT_REND_RENDERER_SELECTION_CREND,
+ ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV,
+ ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN,
+ ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND,
+ ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT,
+
+} ISAR_SPLIT_REND_RENDERER_SELECTION;
+
+typedef struct _ISAR_SPLIT_REND_BITS_DATA
+{
+ uint8_t *bits_buf;
+ int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/
+ int32_t bits_written;
+ int32_t bits_read;
+ int16_t codec_frame_size_ms;
+ ISAR_SPLIT_REND_CODEC codec;
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t isar_frame_size_ms;
+ int16_t lc3plus_highres;
+#endif
+
+} ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE;
+
+typedef struct _ISAR_SPLIT_REND_CONFIG
+{
+ int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */
+ int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */
+ int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/
+ /*The axis can be set dynamically per frame based on a file input */
+ /*possible values:
+ 1 - (1dof correction. By default YAW correction)
+ 2 - (2dof correction. By default YAW and PITCH correction)
+ 3 - (3dof correction. By default YAW, PITCH and ROLL correction)
+ */
+ int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t isar_frame_size_ms; /* ISAR bit stream frame size in milliseconds */
+#endif
+ int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode;
+ ISAR_SPLIT_REND_CODEC codec;
+ ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t lc3plus_highres;
+#endif
+
+} ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE;
+#endif
+
/*----------------------------------------------------------------------------------*
* Renderer API structures and enums
*----------------------------------------------------------------------------------*/
+#ifdef DEBUGGING
+typedef enum
+{
+ IVAS_RENDER_TYPE_OVERRIDE_NONE,
+ IVAS_RENDER_TYPE_OVERRIDE_CREND,
+ IVAS_RENDER_TYPE_OVERRIDE_FASTCONV
+
+} IVAS_RENDER_TYPE_OVERRIDE;
+#endif
typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG
{
@@ -242,10 +347,33 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG
typedef struct _IVAS_RENDER_CONFIG
{
+#ifdef DEBUGGING
+ IVAS_RENDER_TYPE_OVERRIDE renderer_type_override;
+#endif
IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ISAR_SPLIT_REND_CONFIG_DATA split_rend_config;
+#endif
float directivity[IVAS_MAX_NUM_OBJECTS * 3];
Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; // has the following q-factor pattern: {6, 6, 15, 6, 6, 15, 6, 6, 15, 6, 6, 15}
} IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE;
+typedef struct
+{
+ int16_t numSamplesPerChannel;
+ int16_t numChannels;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ int16_t is_cldfb;
+#endif
+} IVAS_REND_AudioBufferConfig;
+
+typedef struct
+{
+ IVAS_REND_AudioBufferConfig config;
+ Word16 q_factor;
+ Word16 *pq_fact;
+ Word32 *data_fx;
+ // Word16 Q_data;
+} IVAS_REND_AudioBuffer;
#endif /* COMMON_API_TYPES_H */
diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h
index 1198008f647080f71550e28f940ff6f115dec98d..8ec9e112b7344300f4029df903dee2e510e77281 100644
--- a/lib_com/ivas_error.h
+++ b/lib_com/ivas_error.h
@@ -97,6 +97,12 @@ typedef enum
* input data errors *
*----------------------------------------*/
IVAS_ERR_INVALID_BITSTREAM = 0x2000,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM,
+ IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG,
+#endif
+#endif
/*----------------------------------------*
* hardware errors *
@@ -135,6 +141,10 @@ typedef enum
IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING,
IVAS_ERR_INVALID_ER_PARAM,
IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IVAS_ERR_LC3PLUS_INVALID_BITRATE,
+ IVAS_ERR_INVALID_SPLIT_REND_CONFIG,
+#endif
/*----------------------------------------*
* unknown error *
@@ -233,6 +243,12 @@ static inline const char *ivas_error_to_string( ivas_error error_code )
return "Wrong mode";
case IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED:
return "Head rotation not supported";
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ case IVAS_ERR_LC3PLUS_INVALID_BITRATE:
+ return "Specified split rendering bit rate is not supported";
+ case IVAS_ERR_INVALID_SPLIT_REND_CONFIG:
+ return "Specified split rendering configuration is invalid";
+#endif
case IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED:
return "External orientation not supported";
case IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED:
diff --git a/lib_rend/ivas_limiter.c b/lib_com/ivas_limiter.c
similarity index 100%
rename from lib_rend/ivas_limiter.c
rename to lib_com/ivas_limiter.c
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index 03bc3d6e5761cb47156dd15f849625fe99545cea..e7827023b40fa3b80aec7a8c8ffd14b764c6ea71 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -42,6 +42,7 @@
#include "stat_com.h"
#include "ivas_stat_enc.h"
#include "ivas_stat_dec.h"
+#include "ivas_stat_rend.h"
#include "ivas_stat_com.h"
#include "ivas_error_utils.h"
diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h
index e7eaea5b798854cffb98729f252518bdaebaa533..cd046cb5bfecf0de892b4a289ed2bd5a61fd226b 100644
--- a/lib_com/ivas_prot_fx.h
+++ b/lib_com/ivas_prot_fx.h
@@ -42,6 +42,7 @@
#include "stat_com.h"
#include "ivas_stat_enc.h"
#include "ivas_stat_dec.h"
+#include "ivas_stat_rend.h"
#include "ivas_stat_com.h"
#include "ivas_error_utils.h"
@@ -2608,6 +2609,52 @@ Word16 getNumChanAnalysis_fx(
Encoder_Struct *st_ivas /* i : IVAS encoder structure */
);
+/*----------------------------------------------------------------------------------*
+ * Limiter prototypes
+ *----------------------------------------------------------------------------------*/
+
+
+ivas_error ivas_limiter_open(
+ IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */
+ const int16_t num_channels, /* i : number of I/O channels */
+ const int32_t sampling_rate /* i : sampling rate for processing */
+);
+
+void ivas_limiter_close(
+ IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */
+);
+
+void ivas_limiter_dec(
+ IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
+ float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
+ const int16_t num_channels, /* i : number of channels to be processed */
+ const int16_t output_frame, /* i : number of samples per channel in the buffer */
+ const int16_t BER_detect /* i : BER detect flag */
+);
+void ivas_limiter_dec_fx(
+ IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
+ Word32 *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
+ const Word16 num_channels, /* i : number of channels to be processed */
+ const Word16 output_frame, /* i : number of samples per channel in the buffer */
+ const Word16 BER_detect, /* i : BER detect flag */
+ Word16 q_factor /* i : Q factor of the output samples */
+);
+void limiter_process(
+ IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
+ const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
+ const float threshold, /* i : signal amplitude above which limiting starts to be applied */
+ const int16_t BER_detect, /* i : BER detect flag */
+ int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */
+);
+void limiter_process_fx(
+ IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
+ const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
+ const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */
+ const Word16 BER_detect, /* i : BER detect flag */
+ Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations (can be NULL) */
+ Word16 q_factor /* i : Q factor of output samples */
+);
+
ivas_error ivas_limiter_open_fx(
IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */
const Word16 max_num_channels, /* i : maximum number of I/O channels to be processed */
@@ -3647,14 +3694,22 @@ ivas_error ivas_allocate_binaural_hrtf_fx(
);
void ivas_binRenderer_fx(
- BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */
- COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/
- const Word16 numTimeSlots, /* i : number of time slots to render */
+ BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+#endif
+ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/
+ const Word16 numTimeSlots, /* i : number of time slots to render */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word32 Cldfb_RealBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
+ Word32 Cldfb_ImagBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
+#else
Word32 Cldfb_RealBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */
Word32 Cldfb_ImagBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */
- Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
- Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
- Word16 *Q_in /* i : LS signals exp */
+#endif
+ Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
+ Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
+ Word16 *Q_in /* i : LS signals exp */
);
void ivas_binaural_add_LFE_fx(
@@ -5855,4 +5910,38 @@ void reset_metadata_spatial_fx(
const Word32 core_brate, /* i : core bitrate */
const Word16 nb_bits_metadata /* i : number of meatdata bits */
);
+
+void Euler2Quat(
+ const float yaw, /* i : yaw (x) */
+ const float pitch, /* i : pitch (y) */
+ const float roll, /* i : roll (z) */
+ IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
+);
+void Euler2Quat_fx(
+ const Word32 yaw, /* i : yaw (x) Q22 */
+ const Word32 pitch, /* i : pitch (y) Q22 */
+ const Word32 roll, /* i : roll (z) Q22 */
+ IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
+);
+float deg2rad(
+ float degrees );
+
+Word32 deg2rad_fx(
+ Word32 degrees );
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+void Quat2EulerDegree(
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ float *yaw, /* o : yaw */
+ float *pitch, /* o : pitch */
+ float *roll /* o : roll */
+);
+void Quat2EulerDegree_fx(
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ Word32 *yaw_fx, /* o : yaw */
+ Word32 *pitch_fx, /* o : pitch */
+ Word32 *roll_fx /* o : roll */
+);
+#endif
+
#endif
diff --git a/lib_com/ivas_rotation_com.c b/lib_com/ivas_rotation_com.c
new file mode 100644
index 0000000000000000000000000000000000000000..d50eb43046e2d90bcae78bacbc133fc57c78e677
--- /dev/null
+++ b/lib_com/ivas_rotation_com.c
@@ -0,0 +1,270 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "ivas_cnst.h"
+#include
+#include
+#include "options.h"
+#include
+#include "cnst.h"
+#include "prot.h"
+#include "ivas_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+#include "prot_fx2.h"
+#include "basop_mpy.h"
+#include "basop_util.h"
+#include "enh64.h"
+/*-------------------------------------------------------------------------
+ * Euler2Quat()
+ *
+ * Calculate corresponding Quaternion from Euler angles in radians
+ *------------------------------------------------------------------------*/
+void Euler2Quat_fx(
+ const Word32 yaw, /* i : yaw (x) Q22 */
+ const Word32 pitch, /* i : pitch (y) Q22 */
+ const Word32 roll, /* i : roll (z) Q22 */
+ IVAS_QUATERNION *quat /* o : quaternion describing the rotation Q19 */
+)
+{
+ Word16 cr = getCosWord16( extract_l( L_shr_r( roll, 10 ) ) ); // Q14
+ Word16 sr = getSinWord16( extract_l( L_shr_r( roll, 10 ) ) );
+ Word16 cp = getCosWord16( extract_l( L_shr_r( pitch, 10 ) ) );
+ Word16 sp = getSinWord16( extract_l( L_shr_r( pitch, 10 ) ) );
+ Word16 cy = getCosWord16( extract_l( L_shr_r( yaw, 10 ) ) );
+ Word16 sy = getSinWord16( extract_l( L_shr_r( yaw, 10 ) ) );
+ quat->w_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( cr, cp ), cy ), Mpy_32_16_1( L_mult0( sr, sp ), sy ) ), 5 ); // Q19
+ move32();
+ quat->x_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( sr, cp ), cy ), Mpy_32_16_1( L_mult0( cr, sp ), sy ) ), 5 ); // Q19
+ move32();
+ quat->y_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( sr, cp ), sy ), Mpy_32_16_1( L_mult0( cr, sp ), cy ) ), 5 ); // Q19
+ move32();
+ quat->z_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( cr, cp ), sy ), Mpy_32_16_1( L_mult0( sr, sp ), cy ) ), 5 ); // Q19
+ move32();
+
+ return;
+}
+void Euler2Quat(
+ const float yaw, /* i : yaw (x) */
+ const float pitch, /* i : pitch (y) */
+ const float roll, /* i : roll (z) */
+ IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
+)
+{
+ float cr = cosf( roll * 0.5f );
+ float sr = sinf( roll * 0.5f );
+ float cp = cosf( pitch * 0.5f );
+ float sp = sinf( pitch * 0.5f );
+ float cy = cosf( yaw * 0.5f );
+ float sy = sinf( yaw * 0.5f );
+ quat->w = cr * cp * cy + sr * sp * sy;
+ quat->x = sr * cp * cy - cr * sp * sy;
+ quat->y = sr * cp * sy + cr * sp * cy;
+ quat->z = cr * cp * sy - sr * sp * cy;
+
+ return;
+}
+
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*-------------------------------------------------------------------------
+ * Quat2EulerDegree()
+ *
+ * Quaternion handling: calculate corresponding Euler angles in degrees
+ *------------------------------------------------------------------------*/
+void Quat2EulerDegree_fx(
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ Word32 *yaw_fx, /* o : yaw */
+ Word32 *pitch_fx, /* o : pitch */
+ Word32 *roll_fx /* o : roll */
+)
+{
+ IF( NE_32( quat.w_fx, L_negate( 12582912 ) /*3.0f in Q22*/ ) )
+ {
+ Word32 tmp1 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.x_fx ), Q22 ) ); // Q22
+ Word32 tmp2 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.z_fx ), Q22 ) ); // Q22
+ Word32 tmp3 = L_shl( L_add( tmp1, tmp2 ), 1 ); // Q22
+
+ Word32 tmp4 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.x_fx ), Q22 ) ); // Q22
+ Word32 tmp5 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22
+ Word32 tmp6 = L_shl( L_add( tmp4, tmp5 ), 1 );
+ Word32 tmp7 = L_sub( ONE_IN_Q22, tmp6 );
+
+ IF( tmp3 >= -2 && tmp3 <= 2 )
+ {
+ tmp3 = 0;
+ }
+ IF( tmp7 >= -2 && tmp7 <= 2 )
+ {
+ tmp7 = 0;
+ }
+
+ Word16 yaw_fx_16 = BASOP_util_atan2( tmp3, tmp7, 0 ); // Q13
+ *yaw_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, yaw_fx_16 );
+
+ Word32 p_fx;
+ Word32 tmp8 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.y_fx ), Q22 ) ); // Q22
+ Word32 tmp9 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.x_fx ), Q22 ) ); // Q22
+ p_fx = L_shl( L_sub( tmp8, tmp9 ), 1 );
+ p_fx = max( L_negate( ONE_IN_Q22 ), min( ONE_IN_Q22, p_fx ) ); // Q22
+
+ Word32 p_fx_sq = W_extract_l( W_shr( W_mult0_32_32( p_fx, p_fx ), Q22 ) );
+ Word16 res_exp = 0;
+ Word32 one_minus_p_fx_sq = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( p_fx_sq ), 31 - Q22, &res_exp );
+ Word32 sqrt_one_minus_p_fx_sq = Sqrt32( one_minus_p_fx_sq, &res_exp );
+
+ Word16 pitch_fx_16 = BASOP_util_atan2( p_fx, sqrt_one_minus_p_fx_sq, ( 31 - Q22 ) - res_exp );
+
+ *pitch_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, pitch_fx_16 );
+
+ Word32 tmp10 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.z_fx ), Q22 ) ); // Q22
+ Word32 tmp11 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.y_fx ), Q22 ) ); // Q22
+ Word32 tmp12 = L_shl( L_add( tmp10, tmp11 ), 1 ); // Q22
+
+ Word32 tmp13 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22
+ Word32 tmp14 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.z_fx ), Q22 ) ); // Q22
+ Word32 tmp15 = L_shl( L_add( tmp13, tmp14 ), 1 ); // Q22
+ Word32 tmp16 = L_sub( ONE_IN_Q22, tmp15 ); // Q22
+
+ IF( tmp12 >= -2 && tmp12 <= 2 )
+ {
+ tmp12 = 0;
+ }
+ IF( tmp16 >= -2 && tmp16 <= 2 )
+ {
+ tmp16 = 0;
+ }
+ Word16 roll_fx_16 = BASOP_util_atan2( tmp12, tmp16, 0 ); // Q13
+ *roll_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, roll_fx_16 );
+ }
+ ELSE
+ {
+ /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention
+ *
+ * yaw: rotate scene counter-clockwise in the horizontal plane
+ * pitch: rotate scene in the median plane, increase elevation with positive values
+ * roll: rotate scene from the right ear to the top
+ */
+ *yaw_fx = quat.z_fx;
+ *pitch_fx = quat.y_fx;
+ *roll_fx = quat.x_fx;
+ }
+
+ return;
+}
+
+void Quat2EulerDegree(
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ float *yaw, /* o : yaw */
+ float *pitch, /* o : pitch */
+ float *roll /* o : roll */
+)
+{
+ if ( quat.w != -3.0 )
+ {
+ float p;
+
+ *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) );
+
+ p = 2 * ( quat.w * quat.y - quat.z * quat.x );
+ p = max( -1.0f, min( 1.0f, p ) );
+ *pitch = asinf( p );
+
+ *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) );
+
+ *yaw *= _180_OVER_PI;
+ *pitch *= _180_OVER_PI;
+ *roll *= _180_OVER_PI;
+ }
+ else
+ {
+ /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention
+ *
+ * yaw: rotate scene counter-clockwise in the horizontal plane
+ * pitch: rotate scene in the median plane, increase elevation with positive values
+ * roll: rotate scene from the right ear to the top
+ */
+ *yaw = quat.z;
+ *pitch = quat.y;
+ *roll = quat.x;
+ }
+
+ return;
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * deg2rad()
+ *
+ * Converts degrees to normalized radians
+ *------------------------------------------------------------------------*/
+#define DEGREE_180 ( Word32 )( 180.0 * ONE_IN_Q22 )
+#define DEGREE_360 ( Word32 )( 360.0 * ONE_IN_Q22 )
+#define PI_OVER_180_FX ( Word32 )( ( EVS_PI / 180.0f ) * ONE_IN_Q31 )
+/*-------------------------------------------------------------------------
+ * deg2rad()
+ *
+ * Converts degrees to normalized radians
+ *------------------------------------------------------------------------*/
+Word32 deg2rad_fx(
+ Word32 degrees // Q23
+)
+{
+ WHILE( GE_32( degrees, DEGREE_180 ) )
+ {
+ degrees = L_sub( degrees, DEGREE_360 );
+ }
+ WHILE( LE_32( degrees, -DEGREE_180 ) )
+ {
+ degrees = L_add( degrees, DEGREE_360 );
+ }
+
+ return Mpy_32_32( PI_OVER_180_FX, degrees ); // Q23
+}
+
+}
+float deg2rad(
+ float degrees )
+{
+ while ( degrees >= 180.0f )
+ {
+ degrees = degrees - 360.0f;
+ }
+ while ( degrees <= -180.0f )
+ {
+ degrees = degrees + 360.0f;
+ }
+
+ return PI_OVER_180 * degrees;
+}
diff --git a/lib_com/options.h b/lib_com/options.h
index 250116483affc4153e758b3f7ce4e70b242e8ae7..515c576f1da6c5de46a4df1871aabda5dc41e6da 100644
--- a/lib_com/options.h
+++ b/lib_com/options.h
@@ -123,4 +123,10 @@
#define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/
#define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */
#define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */
+
+#define SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#define SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+#define ISAR_BITSTREAM_UPDATE_LC3PLUS /* FhG: Multiple improvements to the ISAR bitstream when LC3plus is used. See MR 1456 for details. */
+#endif
#endif
diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c
index 36246f73923c7b643e2709a7b7fc6faa71ace490..bc31e32e816c3cf6e53d186b666f764f31c300a6 100644
--- a/lib_dec/ivas_binRenderer_internal.c
+++ b/lib_dec/ivas_binRenderer_internal.c
@@ -63,7 +63,12 @@ static void ivas_binRenderer_filterModule_fx(
Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals Q_curr*/
Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals Q_curr*/
const Word16 numTimeSlots, /* i : number of time slots to process */
- BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
+ const Word16 pos_idx, /* i : pose index */
+#else
+ BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
+#endif
Word16 Q_curr )
{
Word16 bandIdx, k, chIdx, tapIdx;
@@ -75,9 +80,15 @@ static void ivas_binRenderer_filterModule_fx(
{
FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx][0] );
+ filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx][0] );
+ Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx][0] );
+#else
filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] );
filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] );
Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] );
+#endif
filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29
filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29
@@ -180,9 +191,18 @@ static ivas_error ivas_binRenderer_convModuleOpen(
const Word16 renderer_type,
const Word16 isLoudspeaker,
const AUDIO_CONFIG input_config,
- const HRTFS_FASTCONV_HANDLE hHrtf )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ const HRTFS_FASTCONV_HANDLE hHrtf,
+ const Word16 num_poses
+#else
+ const HRTFS_FASTCONV_HANDLE hHrtf
+#endif
+)
{
Word16 bandIdx, chIdx;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 pos_idx;
+#endif
BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
@@ -308,7 +328,77 @@ static ivas_error ivas_binRenderer_convModuleOpen(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ if ( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ****) malloc( num_poses * sizeof( Word16 *** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+ if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx] = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
+ {
+ if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
+ {
+ if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+
+ IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
+ }
+ }
+ }
+ }
+#else
IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
@@ -359,6 +449,7 @@ static ivas_error ivas_binRenderer_convModuleOpen(
}
}
}
+#endif
/* set memories */
FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
{
diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c
index 95cca12a098cc772bf24cc54c6a5b604e95565e5..46cb389bf8de2b5bf574ca728ddb79da65a4c3da 100644
--- a/lib_dec/ivas_dirac_dec.c
+++ b/lib_dec/ivas_dirac_dec.c
@@ -980,6 +980,9 @@ ivas_error ivas_dirac_dec_config_fx(
Word16 need_parambin;
Word16 dec_param_estim_old;
Word16 dec_param_estim_new;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 num_poses, pos_idx;
+#endif
error = IVAS_ERR_OK;
move32();
@@ -1010,6 +1013,16 @@ ivas_error ivas_dirac_dec_config_fx(
move16();
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ num_poses = 1;
+ move16();
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+ move16();
+ }
+#endif
+
sparfoa_flag = 0;
move16();
test();
@@ -1056,7 +1069,11 @@ ivas_error ivas_dirac_dec_config_fx(
IF( !need_parambin )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
}
need_dirac_rend = 0;
@@ -1129,7 +1146,11 @@ ivas_error ivas_dirac_dec_config_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] == NULL )
+#else
IF( st_ivas->hDiracDecBin == NULL )
+#endif
{
IF( NE_32( ( error = ivas_dirac_dec_init_binaural_data_fx( st_ivas, st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
{
@@ -1141,34 +1162,75 @@ ivas_error ivas_dirac_dec_config_fx(
/* This is required to keep BE in rate switching. This probably means that 1TC and 2TC MASA perform differently. */
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params != NULL && !( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->nSCE > 0 ) )
+#else
IF( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params != NULL && !( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->nSCE > 0 ) )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_decorr_close_fx( &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ); // done
+#else
ivas_dirac_dec_decorr_close_fx( &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ); // done
+#endif
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+#else
IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+#endif
{
return error;
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /* copy td-decorr flag to split renderer side rendereres */
+ FOR( pos_idx = 1; pos_idx < num_poses; pos_idx++ )
+ {
+ st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr;
+ }
+ IF( !st_ivas->hDiracDecBin[0]->useTdDecorr )
+#else
IF( !st_ivas->hDiracDecBin->useTdDecorr )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params == NULL )
+#else
IF( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params == NULL )
+#endif
{
Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX];
ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands );
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS,
+ DIRAC_SYNTHESIS_PSD_LS, frequency_axis_fx, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS,
DIRAC_SYNTHESIS_PSD_LS, frequency_axis_fx, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ),
IVAS_ERR_OK ) )
{
return error;
}
+#endif
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+ st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
+ move16();
+ }
+#else
st_ivas->hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
move16();
+#endif
}
}
}
@@ -2185,8 +2247,13 @@ void ivas_dirac_dec_render_sf_fx(
/*CLDFB: last output channels reserved to LFT for CICPx*/
Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#else
Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#endif
Word16 index = 0, num_freq_bands = 0;
move16();
move16();
@@ -3712,7 +3779,29 @@ void ivas_dirac_dec_render_sf_fx(
input_q = Q6;
move16();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
+ {
+ FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ FOR( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands );
+ Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands );
+ }
+ }
+ st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
+ move16();
+ }
+ }
+#endif
+
ivas_binRenderer_fx( st_ivas->hBinRenderer,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
+#endif
st_ivas->hCombinedOrientationData,
hSpatParamRendCom->subframe_nbslots[subframe_idx],
Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx,
@@ -3721,6 +3810,24 @@ void ivas_dirac_dec_render_sf_fx(
Scale_sig32( Cldfb_RealBuffer_Binaural_fx[0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6
Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ Word16 pos_idx;
+ FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
+ {
+ FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[( add( i_mult( pos_idx, BINAURAL_CHANNELS ) ), ch )][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); // Q6
+ Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[( add( i_mult( pos_idx, BINAURAL_CHANNELS ) ), ch )][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); // Q6
+ }
+ }
+ }
+ }
+#endif
+
/* Inverse CLDFB*/
FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
{
@@ -3730,10 +3837,17 @@ void ivas_dirac_dec_render_sf_fx(
Word32 *ImagBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i];
+ move32();
+ ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i];
+ move32();
+#else
RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i];
move32();
ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i];
move32();
+#endif
}
scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6-1
diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c
index 35844b5e53d3dd214665bfcf932501ccb765daaf..8fe884c3f843b878ca0d8860f7e0b7bf9c1bbba5 100644
--- a/lib_dec/ivas_init_dec.c
+++ b/lib_dec/ivas_init_dec.c
@@ -44,6 +44,11 @@
#include "wmc_auto.h"
#include "prot_fx.h"
#include "ivas_prot_fx.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "lib_isar_pre_rend.h"
+#include "isar_prot.h"
+#include "isar_stat.h"
+#endif
/*-------------------------------------------------------------------*
@@ -55,6 +60,215 @@ static ivas_error ivas_read_format( Decoder_Struct *st_ivas, Word16 *num_bits_re
static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas );
+
+
+/*-------------------------------------------------------------------*
+ * ivas_dec_reconfig_split_rend()
+ *
+ * IVAS decoder split rend reconfig
+ *-------------------------------------------------------------------*/
+
+static ivas_error ivas_dec_reconfig_split_rend(
+ Decoder_Struct *st_ivas /* i : IVAS decoder structure */
+)
+{
+ ivas_error error;
+ Word16 cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag;
+ SPLIT_REND_WRAPPER *hSplitRendWrapper;
+
+ hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend;
+ move16();
+ pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0;
+ move16();
+ cldfb_in_flag = 0;
+ move16();
+
+ IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ cldfb_in_flag = 1;
+ move16();
+ }
+
+ ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS );
+
+ isCldfbNeeded = 0;
+ move16();
+
+ IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ||
+ ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) )
+ {
+ cldfb_in_flag = 0;
+ move16();
+ }
+
+ IF( NE_16( st_ivas->renderer_type, RENDERER_DISABLE ) )
+ {
+ IF( EQ_16( cldfb_in_flag, 0 ) )
+ {
+ isCldfbNeeded = 1;
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->hRenderConfig->split_rend_config.codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag )
+ {
+ isCldfbNeeded = 1;
+ move16();
+ }
+ ELSE IF( pcm_out_flag && cldfb_in_flag )
+ {
+ isCldfbNeeded = 1;
+ move16();
+ }
+ }
+ ELSE IF( st_ivas->hDecoderConfig->Opt_non_diegetic_pan )
+ {
+ isCldfbNeeded = 1;
+ move16();
+ }
+
+ IF( EQ_16( isCldfbNeeded, 1 ) && hSplitRendWrapper->hCldfbHandles == NULL )
+ {
+ IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) );
+ }
+
+ num_ch = i_mult( MAX_HEAD_ROT_POSES, BINAURAL_CHANNELS );
+ move16();
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL;
+ move16();
+ }
+
+ num_ch = i_mult( hSplitRendWrapper->multiBinPoseData.num_poses, BINAURAL_CHANNELS );
+ move16();
+
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ IF( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) );
+ }
+ }
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ if ( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ ELSE IF( EQ_16( isCldfbNeeded, 0 ) && hSplitRendWrapper->hCldfbHandles != NULL )
+ {
+ num_ch = i_mult( MAX_HEAD_ROT_POSES, BINAURAL_CHANNELS );
+ move16();
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ IF( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL )
+ {
+ deleteCldfb_ivas_fx( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] );
+ hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL;
+ move32();
+ }
+ }
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ IF( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL )
+ {
+ deleteCldfb_ivas_fx( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] );
+ hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL;
+ move32();
+ }
+ }
+
+ free( hSplitRendWrapper->hCldfbHandles );
+ hSplitRendWrapper->hCldfbHandles = NULL;
+ move32();
+ }
+
+ IF( ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) ) &&
+ ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) &&
+ !( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) ) /* td-rend not needed? */
+ {
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i )
+ {
+ IF( st_ivas->hTdRendHandles[i] != NULL )
+ {
+ st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL;
+ move32();
+ ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] );
+ }
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_dec_init_split_rend()
+ *
+ * IVAS decoder split rend init
+ *-------------------------------------------------------------------*/
+
+static ivas_error ivas_dec_init_split_rend(
+ Decoder_Struct *st_ivas /* i : IVAS decoder structure */
+)
+{
+ ivas_error error;
+ Word16 cldfb_in_flag, pcm_out_flag;
+ Word16 mixed_td_cldfb_flag;
+
+ pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0;
+ cldfb_in_flag = 0;
+ move16();
+
+ IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ cldfb_in_flag = 1;
+ move16();
+ }
+
+ ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS );
+
+ IF( EQ_16( cldfb_in_flag, 1 ) && ( EQ_16( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) )
+ {
+ IF( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) );
+ }
+ }
+
+ mixed_td_cldfb_flag = 0;
+ move16();
+ IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ||
+ ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) )
+ {
+ mixed_td_cldfb_flag = 1;
+ move16();
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag );
+ move16();
+#else
+ error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag );
+ move16();
+#endif
+ return error;
+}
+#endif
+
/*-------------------------------------------------------------------*
* ivas_dec_setup()
*
@@ -524,6 +738,20 @@ ivas_error ivas_dec_setup(
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /*-----------------------------------------------------------------*
+ * reconfig split rendering as renderer might change after bitrate switching
+ *-----------------------------------------------------------------*/
+
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#endif
+
/*----------------------------------------------------------------*
* Reset bitstream pointers
*----------------------------------------------------------------*/
@@ -958,7 +1186,12 @@ ivas_error ivas_init_decoder_front(
*--------------------------------------------------------------------*/
test();
test();
- IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ||
+ ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && st_ivas->hDecoderConfig->Opt_non_diegetic_pan )
+#endif
+ )
{
IF( NE_32( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ), IVAS_ERR_OK ) )
{
@@ -1133,6 +1366,20 @@ ivas_error ivas_init_decoder_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /*-----------------------------------------------------------------*
+ * Initialize binuaral split rendering
+ *-----------------------------------------------------------------*/
+
+ IF( st_ivas->hSplitBinRend != NULL && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ||
+ ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && EQ_16( st_ivas->hRenderConfig->split_rend_config.dof, 0 ) ) ) )
+ {
+ IF( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#endif
/*-----------------------------------------------------------------*
* Allocate and initialize SCE/CPE and other handles
@@ -2071,9 +2318,15 @@ ivas_error ivas_init_decoder_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config,
+ st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ),
+ IVAS_ERR_OK ) )
+#else
IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config,
st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ),
IVAS_ERR_OK ) )
+#endif
{
return error;
}
@@ -2237,6 +2490,9 @@ ivas_error ivas_init_decoder_fx(
{
IF( st_ivas->hBinRenderer->render_lfe )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+#endif
{
/* Account for filterbank delay */
binauralization_delay_ns = L_add( binauralization_delay_ns, IVAS_FB_DEC_DELAY_NS );
@@ -2586,7 +2842,14 @@ void ivas_initialize_handles_dec(
/* rendering handles */
st_ivas->hBinRenderer = NULL;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ )
+ {
+ st_ivas->hDiracDecBin[i] = NULL;
+ }
+#else
st_ivas->hDiracDecBin = NULL;
+#endif
st_ivas->hDirACRend = NULL;
st_ivas->hSpatParamRendCom = NULL;
st_ivas->hLsSetUpConversion = NULL;
@@ -2611,7 +2874,13 @@ void ivas_initialize_handles_dec(
st_ivas->hExtOrientationData = NULL;
st_ivas->hCombinedOrientationData = NULL;
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ st_ivas->hSplitBinRend = NULL;
+ for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i )
+ {
+ st_ivas->hTdRendHandles[i] = NULL;
+ }
+#endif
/* JBM handles */
st_ivas->hTcBuffer = NULL;
st_ivas->hJbmMetadata = NULL;
@@ -2748,12 +3017,31 @@ void ivas_destroy_dec_fx(
/* Fastconv binaural renderer handle */
ivas_binRenderer_close_fx( &st_ivas->hBinRenderer );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /* TD binaural renderer handles */
+ for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i )
+ {
+ if ( st_ivas->hTdRendHandles[i] != NULL )
+ {
+ st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL;
+ ivas_td_binaural_close_fx( &st_ivas->hTdRendHandles[i] );
+ }
+ }
+#endif
+
/* Parametric binaural renderer handle */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
/* Crend handle */
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
+#else
ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) );
+#endif
/* Reverb handle */
ivas_reverb_close( &st_ivas->hReverb );
@@ -2919,7 +3207,12 @@ void ivas_init_dec_get_num_cldfb_instances(
move16();
}
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( st_ivas->hDiracDecBin[0]->useTdDecorr )
+#else
IF( st_ivas->hDiracDecBin->useTdDecorr )
+#endif
{
*numCldfbAnalyses = add( *numCldfbAnalyses, 2 );
move16();
@@ -3206,12 +3499,22 @@ static ivas_error doSanityChecks_IVAS(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) && NE_16( output_Fs, 48000 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." );
+ }
+#endif
IF( st_ivas->hDecoderConfig->Opt_Headrotation )
{
test();
test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ ) )
{
return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" );
}
diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c
index a5f7f7b06ff1223ef66e62eb8d8786967a715773..6f1ae3de8c978cdcbdf71c8a5c3f16111a23c58d 100644
--- a/lib_dec/ivas_ism_dec.c
+++ b/lib_dec/ivas_ism_dec.c
@@ -198,10 +198,18 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx(
ivas_param_ism_dec_close_fx( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config );
test();
- IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
/* close the parametric binaural renderer */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
/* Open the TD Binaural renderer */
test();
IF( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL )
@@ -234,13 +242,24 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx(
IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) )
{
/* close the parametric binaural renderer */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
/* Open Crend Binaural renderer */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
{
return error;
}
+#endif
st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns;
move32();
@@ -258,7 +277,11 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx(
}
test();
- IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
/* open the parametric binaural renderer */
IF( NE_32( ( error = ivas_dirac_dec_binaural_copy_hrtfs_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
@@ -303,7 +326,11 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx(
}
/* close the crend binaural renderer */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
+#else
ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) );
+#endif
}
}
diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c
index 9514e5e2a13cf92647264eae718bfc698d9789ff..50d1811f65225460014950d77b975ada187a180e 100644
--- a/lib_dec/ivas_ism_param_dec.c
+++ b/lib_dec/ivas_ism_param_dec.c
@@ -556,7 +556,11 @@ static ivas_error ivas_param_ism_rendering_init_fx(
test();
test();
test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ ) )
{
/* computation of proto matrix */
ivas_ism_get_proto_matrix_fx( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix_fx );
@@ -734,7 +738,11 @@ ivas_error ivas_param_ism_dec_open_fx(
test();
test();
IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ||
- EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
+ EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ ) )
{
/* Initialize efap handle */
IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth_fx, hOutSetup.ls_elevation_fx, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
@@ -757,7 +765,11 @@ ivas_error ivas_param_ism_dec_open_fx(
test();
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 1 ) ), IVAS_ERR_OK ) )
{
diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c
index d69fa852593acbfeb82f9af47792f4ad2fb6cd19..0f762462c75190d9b994f125c19fcaf17f28b81f 100644
--- a/lib_dec/ivas_jbm_dec.c
+++ b/lib_dec/ivas_jbm_dec.c
@@ -1688,11 +1688,19 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx(
test();
/* delay the objects here for all renderers where it is needed */
IF(
- EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
- EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
- EQ_16( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
- EQ_16( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
- EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ (
+#endif
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
+ EQ_16( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
+ EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ) &&
+ ( NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+#endif
+ )
{
FOR( n = 0; n < st_ivas->nchan_ism; n++ )
{
@@ -1872,6 +1880,9 @@ ivas_error ivas_jbm_dec_render_fx(
const Word16 output_q_factor = Q11;
move16();
SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 nchan_out_syn_output;
+#endif
push_wmops( "ivas_dec_render" );
/*----------------------------------------------------------------*
@@ -2064,6 +2075,26 @@ ivas_error ivas_jbm_dec_render_fx(
#endif
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /* Binaural rendering */
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
+ {
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural_fx( st_ivas, p_output_fx, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+#else
/* Binaural rendering */
IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
{
@@ -2072,6 +2103,7 @@ ivas_error ivas_jbm_dec_render_fx(
return error;
}
}
+#endif
ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
{
st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
@@ -2090,10 +2122,19 @@ ivas_error ivas_jbm_dec_render_fx(
{
scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11
}
+
+#if defined SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs ) ), IVAS_ERR_OK ) )
{
return error;
}
+#endif
+
FOR( i = 0; i < nchan_out; i++ )
{
scale_sig32( p_output_fx[i], *nSamplesRendered, sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
@@ -2314,14 +2355,40 @@ ivas_error ivas_jbm_dec_render_fx(
scale_sig32( p_tc_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11
}
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+#endif
+
+#if defined SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
&st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs ) ),
IVAS_ERR_OK ) )
{
return error;
}
+#endif
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
FOR( i = 0; i < nchan_in; i++ )
{
@@ -2345,12 +2412,26 @@ ivas_error ivas_jbm_dec_render_fx(
}
ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
{
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
{
- return error;
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_splitBinaural_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
}
+ else
+ {
+#endif
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ }
+#endif
}
}
ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
@@ -2362,7 +2443,13 @@ ivas_error ivas_jbm_dec_render_fx(
/* Rendering */
IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && !st_ivas->hDecoderConfig->Opt_Headrotation )
{
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /*handled in CLDFB domain already*/
+ IF( NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+#endif
+ {
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx );
+ }
}
ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
{
@@ -2578,6 +2665,20 @@ ivas_error ivas_jbm_dec_render_fx(
move16();
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ nchan_out_syn_output = i_mult( BINAURAL_CHANNELS, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
+ move16();
+ }
+ ELSE
+ {
+ nchan_out_syn_output = nchan_out;
+ move16();
+ }
+
+ IF( st_ivas->hDecoderConfig->Opt_Limiter )
+#endif
{
IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) )
{
@@ -2587,7 +2688,11 @@ ivas_error ivas_jbm_dec_render_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out_syn_output, data );
+#else
ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out, data );
+#endif
*nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available;
move16();
@@ -2713,12 +2818,21 @@ ivas_error ivas_jbm_dec_flush_renderer_fx(
st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
*st_ivas->hCrendWrapper->p_io_qfactor = 11;
move16();
+#if defined SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
+ NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ),
IVAS_ERR_OK ) )
{
return error;
}
+#endif
}
}
ELSE
@@ -2745,12 +2859,22 @@ ivas_error ivas_jbm_dec_flush_renderer_fx(
}
*st_ivas->hCrendWrapper->p_io_qfactor = 11;
move16();
+
+#if defined SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+#else
IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ),
IVAS_ERR_OK ) )
{
return error;
}
+#endif
ivas_binaural_add_LFE_fx( st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc_fx, p_output_fx );
}
@@ -2866,6 +2990,9 @@ ivas_error ivas_jbm_dec_flush_renderer_fx(
*nSamplesRendered = n_samples_to_render;
move16();
/* Only write out the valid data*/
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDecoderConfig->Opt_Limiter )
+#endif
{
IF( NE_16( st_ivas->ivas_format, MONO_FORMAT ) )
{
diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c
index 983eb33095e6d03432387deede2d78b3c3a9270b..e87d5da00c1252a3b57139e0ef16991041b29556 100644
--- a/lib_dec/ivas_masa_dec.c
+++ b/lib_dec/ivas_masa_dec.c
@@ -1581,6 +1581,9 @@ ivas_error ivas_masa_dec_reconfigure_fx(
Word16 numCldfbAnalyses_old, numCldfbSyntheses_old;
ivas_error error;
Word32 ism_total_brate;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 pos_idx;
+#endif
error = IVAS_ERR_OK;
move16();
@@ -1611,8 +1614,13 @@ ivas_error ivas_masa_dec_reconfigure_fx(
test();
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) ||
+ ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] == NULL ) )
+#else
IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) ||
( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin == NULL ) )
+#endif
{
/* init a new DirAC dec */
if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
@@ -1625,7 +1633,11 @@ ivas_error ivas_masa_dec_reconfigure_fx(
IF( st_ivas->hDirAC != NULL )
{
/* close all unnecessary parametric decoding and rendering */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
@@ -1676,7 +1688,11 @@ ivas_error ivas_masa_dec_reconfigure_fx(
test();
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL )
+#else
IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL )
+#endif
{
if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
{
@@ -1732,7 +1748,11 @@ ivas_error ivas_masa_dec_reconfigure_fx(
test();
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) )
+#else
IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) )
+#endif
{
if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
{
@@ -1750,7 +1770,11 @@ ivas_error ivas_masa_dec_reconfigure_fx(
test();
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) )
+#else
IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) )
+#endif
{
if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
{
@@ -1760,12 +1784,24 @@ ivas_error ivas_masa_dec_reconfigure_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ IF( st_ivas->hDiracDecBin[pos_idx] != NULL )
+ {
+ /* regularization factor is bitrate-dependent */
+ st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
+ move16();
+ }
+ }
+#else
IF( st_ivas->hDiracDecBin != NULL )
{
/* regularization factor is bitrate-dependent */
st_ivas->hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
move16();
}
+#endif
test();
IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */
@@ -1773,9 +1809,17 @@ ivas_error ivas_masa_dec_reconfigure_fx(
/*-----------------------------------------------------------------*
* TD Decorrelator
*-----------------------------------------------------------------*/
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] != NULL )
+#else
IF( st_ivas->hDiracDecBin != NULL )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+#else
IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+#endif
{
return error;
}
@@ -2012,7 +2056,11 @@ void ivas_spar_param_to_masa_param_mapping_fx(
move16();
hSpatParamRendCom->numSimultaneousDirections = 1;
move16();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist;
+#else
hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist;
+#endif
nchan_transport = st_ivas->nchan_transport;
move16();
band_grouping = hDirAC->band_grouping;
diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c
index 4175d15def0080ebd3dd76978dc5135a43141db3..7e96c07174a569dd6978fa9d244871f76ef701ba 100644
--- a/lib_dec/ivas_mc_param_dec.c
+++ b/lib_dec/ivas_mc_param_dec.c
@@ -1844,8 +1844,13 @@ void ivas_param_mc_dec_render_fx(
/*CLDFB*/
Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+#else
Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#endif
Word32 *p_output_f_fx[MAX_OUTPUT_CHANNELS];
FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
{
@@ -2179,8 +2184,31 @@ void ivas_param_mc_dec_render_fx(
{
Word16 input_q = 6;
move16();
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
+ {
+ FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands );
+ Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands );
+ }
+ }
+ st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
+ move16();
+ }
+ }
+#endif
+
/* Implement binaural rendering */
ivas_binRenderer_fx( st_ivas->hBinRenderer,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
+#endif
st_ivas->hCombinedOrientationData,
hParamMC->subframe_nbslots[subframe_idx],
Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx,
@@ -2207,6 +2235,25 @@ void ivas_param_mc_dec_render_fx(
Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6
}
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ int16_t pos_idx;
+ FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
+ {
+ FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ FOR( ch = 0; ch < nchan_out_cldfb; ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands );
+ Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands );
+ }
+ }
+ }
+ }
+#endif
+
/* update combined orientation access index */
ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] );
}
@@ -2230,8 +2277,13 @@ void ivas_param_mc_dec_render_fx(
{
IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i]; // Q6
+ ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i]; // Q6
+#else
RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i]; // Q6
ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i]; // Q6
+#endif
}
ELSE
{
diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c
index c1bf455a5f60063f955fff29a969e716e2b9aba9..f998b0d1b8579a2d4c56ed859a9c639e0c9b96d9 100644
--- a/lib_dec/ivas_mc_paramupmix_dec.c
+++ b/lib_dec/ivas_mc_paramupmix_dec.c
@@ -723,13 +723,24 @@ static void ivas_mc_paramupmix_dec_sf(
Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
#endif // MSAN_FIX
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ int16_t slot_index_start;
+#else
Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#endif
hMCParamUpmix = st_ivas->hMCParamUpmix;
assert( hMCParamUpmix );
push_wmops( "ivas_mc_paramupmix_dec_sf" );
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ slot_index_start = st_ivas->hTcBuffer->slots_rendered;
+#endif
+
FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ )
{
pPcm_temp_fx[2 * i] = output_fx[i + 4]; /* un-decorrelated Q11*/
@@ -844,14 +855,40 @@ static void ivas_mc_paramupmix_dec_sf(
Word16 input_q = 6;
move16();
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ /*LFE handling for split rendering cases*/
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
+ {
+ FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ )
+ {
+ FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][add( slot_index_start, slot_idx )], maxBand );
+ Copy32( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][add( slot_index_start, slot_idx )], maxBand );
+ }
+ }
+
+ st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
+ move16();
+ }
+ }
+#endif
+
/* Implement binaural rendering */
ivas_binRenderer_fx( st_ivas->hBinRenderer,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
+#endif
st_ivas->hCombinedOrientationData,
st_ivas->hTcBuffer->subframe_nbslots[subframeIdx],
Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx,
Cldfb_RealBuffer_subfr_fx,
Cldfb_ImagBuffer_subfr_fx, &input_q );
+
FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ )
{
FOR( Word16 idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++ )
@@ -860,6 +897,25 @@ static void ivas_mc_paramupmix_dec_sf(
Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( 6, input_q ) ); // Q6
}
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ int16_t pos_idx;
+ FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
+ {
+ FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
+ {
+ FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
+ {
+ Copy32( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_index_start, slot_idx )], maxBand );
+ Copy32( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_index_start, slot_idx )], maxBand );
+ }
+ }
+ }
+ }
+#endif
+
/* Implement CLDFB synthesis */
FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
@@ -868,8 +924,13 @@ static void ivas_mc_paramupmix_dec_sf(
FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[0][ch][slot_idx]; // Q6
+ ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[0][ch][slot_idx]; // Q6
+#else
RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch][slot_idx]; // Q6
ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch][slot_idx]; // Q6
+#endif
}
scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5
st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5;
diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c
index f3afead8fe1b8c7a8c86783f0c498986ebff91c5..8e34d6642d6ccf02b70a5a2f536b59f6fd567a61 100644
--- a/lib_dec/ivas_mct_dec.c
+++ b/lib_dec/ivas_mct_dec.c
@@ -1455,7 +1455,11 @@ static ivas_error ivas_mc_dec_reconfig_fx(
test();
test();
test();
- IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
/* remove unneeded binaural renderers */
test();
@@ -1470,10 +1474,17 @@ static ivas_error ivas_mc_dec_reconfig_fx(
test();
test();
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend[0] != NULL ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || NE_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) )
+#else
IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || NE_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) )
+#endif
{
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
+#else
ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) );
+#endif
}
test();
@@ -1486,13 +1497,21 @@ static ivas_error ivas_mc_dec_reconfig_fx(
}
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] != NULL )
+#else
IF( st_ivas->hDiracDecBin != NULL )
+#endif
{
test();
test();
IF( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin );
+#else
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+#endif
}
}
@@ -1517,22 +1536,39 @@ static ivas_error ivas_mc_dec_reconfig_fx(
}
IF( EQ_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper, 1 ) ) != IVAS_ERR_OK )
+#else
IF( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper ) ) != IVAS_ERR_OK )
+#endif
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" );
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ st_ivas->hCrendWrapper->hCrend[0] = NULL;
+ st_ivas->hCrendWrapper->hHrtfCrend = NULL;
+ IF( ( st_ivas->hCrendWrapper->hCrend[0] = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" );
+ }
+#else
st_ivas->hCrendWrapper->hCrend = NULL;
st_ivas->hCrendWrapper->hHrtfCrend = NULL;
IF( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" );
}
+#endif
}
}
ELSE IF( st_ivas->hCrendWrapper == NULL && ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) )
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK )
+#else
IF( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c
index 256ce8f96bb845a1b711fe3cd2e8b1e3ea420d05..12ed81e072e4b03927868282e1e46553c128bfd7 100644
--- a/lib_dec/ivas_objectRenderer_internal.c
+++ b/lib_dec/ivas_objectRenderer_internal.c
@@ -342,3 +342,158 @@ ivas_error ivas_td_binaural_renderer_sf_fx(
return IVAS_ERR_OK;
}
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*---------------------------------------------------------------------*
+ * ivas_td_binaural_renderer_sf_splitBinaural()
+ *
+ * Render to multiple binaural pairs based on relative head positions for split rendering.
+ *---------------------------------------------------------------------*/
+
+ivas_error ivas_td_binaural_renderer_sf_splitBinaural(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ Word32 *output[], /* i/o: SCE channels / Binaural synthesis */
+ const Word16 nSamplesRendered /* i : number of samples to render */
+)
+{
+ Word16 i;
+ Word16 pos_idx;
+ IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES];
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData;
+ BINAURAL_TD_OBJECT_RENDERER_HANDLE origTdRendHandle;
+ ivas_error error;
+ Word16 original_subframes_rendered;
+ Word16 original_slots_rendered;
+ Word32 *p_bin_output[BINAURAL_CHANNELS];
+ Word32 output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k];
+
+ Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
+
+ pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData;
+ move32();
+
+ /* If not yet allocated, open additional instances of TD renderer */
+ FOR( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i )
+ {
+ IF( st_ivas->hTdRendHandles[i] != NULL )
+ {
+ continue;
+ }
+
+ IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD,
+ st_ivas->hDecoderConfig->output_Fs,
+ st_ivas->nchan_transport,
+ st_ivas->ivas_format,
+ st_ivas->transport_config,
+ st_ivas->hRenderConfig->directivity_fx,
+ st_ivas->hTransSetup,
+ &st_ivas->hTdRendHandles[i],
+ &st_ivas->binaural_latency_ns,
+ SrcInd ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* Save current head positions */
+ FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
+ {
+ originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i];
+ }
+
+ original_subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
+ move16();
+ original_slots_rendered = st_ivas->hTcBuffer->slots_rendered;
+ move16();
+ origTdRendHandle = st_ivas->hBinRendererTd;
+ move32();
+
+ FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ )
+ {
+ /* Update head positions */
+ IF( NE_16( pos_idx, 0 ) )
+ {
+ FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
+ {
+ IF( EQ_32( originalHeadRot[i].w_fx, -1610612736 /* -3.0f in Q29 */ ) )
+ {
+ assert( 0 );
+ }
+ else
+ {
+ st_ivas->hCombinedOrientationData->Quaternions[i].w = -12582912; // Q22
+ move32();
+
+ Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/
+ &st_ivas->hCombinedOrientationData->Quaternions[i].z_fx,
+ &st_ivas->hCombinedOrientationData->Quaternions[i].y_fx,
+ &st_ivas->hCombinedOrientationData->Quaternions[i].x_fx );
+
+ st_ivas->hCombinedOrientationData->Quaternions[i].x_fx = L_add( st_ivas->hCombinedOrientationData->Quaternions[i].x_fx, pMultiBinPoseData->relative_head_poses[pos_idx][0] );
+ st_ivas->hCombinedOrientationData->Quaternions[i].y_fx = L_add( st_ivas->hCombinedOrientationData->Quaternions[i].y_fx, pMultiBinPoseData->relative_head_poses[pos_idx][1] );
+ st_ivas->hCombinedOrientationData->Quaternions[i].z_fx = L_add( st_ivas->hCombinedOrientationData->Quaternions[i].z_fx, pMultiBinPoseData->relative_head_poses[pos_idx][2] );
+ move32();
+ move32();
+ move32();
+
+ Euler2Quat_fx( deg2rad_fx( st_ivas->hCombinedOrientationData->Quaternions[i].x_fx ), deg2rad_fx( st_ivas->hCombinedOrientationData->Quaternions[i].y_fx ), deg2rad_fx( st_ivas->hCombinedOrientationData->Quaternions[i].z_fx ), &st_ivas->hCombinedOrientationData->Quaternions[i] );
+ }
+ }
+ }
+
+ /* set output channels */
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ p_bin_output[i] = output_local[add( i_mult( pos_idx, BINAURAL_CHANNELS ), i )];
+ move32();
+ }
+ st_ivas->hTcBuffer->subframes_rendered = original_subframes_rendered;
+ move16();
+ st_ivas->hTcBuffer->slots_rendered = original_slots_rendered;
+ move16();
+
+ /* update combined orientation access index */
+ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
+
+ /* Render */
+ IF( NE_16( pos_idx, 0 ) )
+ {
+ st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[sub( pos_idx, 1 )];
+ move32();
+ }
+
+ IF( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ Word32 *p_tc[MAX_TRANSPORT_CHANNELS];
+ FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ {
+ p_tc[i] = st_ivas->hTcBuffer->tc[i] + st_ivas->hTcBuffer->n_samples_rendered;
+ }
+ ivas_binaural_add_LFE_fx( st_ivas, nSamplesRendered, p_tc, p_bin_output );
+ }
+ }
+
+ FOR( i = 0; i < i_mult( pMultiBinPoseData->num_poses, BINAURAL_CHANNELS ); i++ )
+ {
+ Copy32( output_local[i], output[i], nSamplesRendered );
+ }
+
+ /* Restore original head rotation */
+ FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
+ {
+ st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i];
+ move32();
+ }
+
+ /* restore original td renderer handle */
+ st_ivas->hBinRendererTd = origTdRendHandle;
+ move32();
+
+ return IVAS_ERR_OK;
+}
+#endif
\ No newline at end of file
diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c
index 50921761651bd8e790087ebe28274583bcce4826..b4f75702509321b7e519164a527cd2d08e19bf31 100644
--- a/lib_dec/ivas_omasa_dec.c
+++ b/lib_dec/ivas_omasa_dec.c
@@ -422,10 +422,17 @@ ivas_error ivas_omasa_dec_config_fx(
* TD Decorrelator
*-----------------------------------------------------------------*/
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] != NULL )
+#else
IF( st_ivas->hDiracDecBin != NULL )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+#else
IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
-
+#endif
{
return error;
}
@@ -761,6 +768,12 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
Word32 *p_sepobj_fx[MAX_NUM_OBJECTS]; // Q11
Word32 data_separated_objects_fx[MAX_NUM_OBJECTS][L_FRAME48k];
move16();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 slot_idx_start;
+
+ slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
+ move16();
+#endif
FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
{
@@ -788,15 +801,64 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
/* reset combined orientation access index before calling the td renderer */
ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
{
- return error;
- }
+ Word16 slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots;
+ Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
+ Word32 *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */
+ Word16 q_cldfb = 11;
+ move16();
- FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
+ FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); n++ )
+ {
+ p_rend_obj[n] = &output_f[n][0];
+ move32();
+ }
+
+ num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
+ move16();
+ nchan_transport_orig = st_ivas->nchan_transport;
+ move16();
+ st_ivas->nchan_transport = st_ivas->nchan_ism;
+ move16();
+
+ IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */
+ {
+ return error;
+ }
+ st_ivas->nchan_transport = nchan_transport_orig;
+ move16();
+ cldfb_slots = *nSamplesRendered / num_cldfb_bands;
+
+ FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n )
+ {
+ FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
+ {
+ cldfbAnalysis_ts_fx_fixed_q( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb );
+
+ /* note: this intentionally differs from OSBA by: no scaling by 0.5 */
+ v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
+ v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
+ }
+ }
+ }
+ else
{
- v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
+#endif
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
+ {
+ v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
}
+#endif
return IVAS_ERR_OK;
}
diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c
index f9d14c995b01d9b822957779f70aa566c90dc42a..b71b73a6a849078ce11046fc3814306b0a87604a 100644
--- a/lib_dec/ivas_osba_dec.c
+++ b/lib_dec/ivas_osba_dec.c
@@ -140,6 +140,12 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx(
Word32 output_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV
Word32 *p_sepobj_fx[BINAURAL_CHANNELS];
Word16 channel_offset;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word16 slot_idx_start;
+
+ slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
+ move16();
+#endif
FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
{
@@ -154,20 +160,71 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx(
return error;
}
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
{
- return error;
- }
+ Word16 slot_idx, num_cldfb_bands, b, nchan_transport_orig;
+ Word16 cldfb_slots;
+ Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
+ Word16 q_cldfb = 11;
+ move16();
+
+ num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
+ move16();
+ nchan_transport_orig = st_ivas->nchan_transport;
+ move16();
+ st_ivas->nchan_transport = st_ivas->nchan_ism;
+ move16();
+ IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ st_ivas->nchan_transport = nchan_transport_orig;
+ move16();
+ cldfb_slots = *nSamplesRendered / num_cldfb_bands;
- FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
+ FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n )
+ {
+ FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
+ {
+ cldfbAnalysis_ts_fx_fixed_q( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb );
+
+ FOR( b = 0; b < num_cldfb_bands; b++ )
+ {
+ st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] =
+ L_add( L_shr( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][add( slot_idx_start, slot_idx )][b], 1 ),
+ L_shr( Cldfb_RealBuffer[b], 1 ) );
+ move32();
+
+ st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] =
+ L_add( L_shr( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][add(slot_idx_start, slot_idx)][b], 1 ),
+ L_shrCldfb_ImagBuffer[b], 1) );
+ move32();
+ }
+ }
+ }
+ }
+ else
{
- Word16 i;
- FOR( i = 0; i < nSamplesAsked; i++ )
+#endif
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
{
- output_fx[n][i] = L_add( L_shr( output_fx[channel_offset + n][i], 1 ), L_shr( p_sepobj_fx[n][i], 1 ) );
- move32();
+ Word16 i;
+ FOR( i = 0; i < nSamplesAsked; i++ )
+ {
+ output_fx[n][i] = L_add( L_shr( output_fx[channel_offset + n][i], 1 ), L_shr( p_sepobj_fx[n][i], 1 ) );
+ move32();
+ }
}
+#ifdef SPLIT_REND_WITH_HEAD_ROT
}
+#endif
return IVAS_ERR_OK;
}
diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c
index 64995d8a0ac9975fc5847f762be5bac13d8ed472..d2aad8218b207a2a04a5830682d9b0fdbead332e 100644
--- a/lib_dec/ivas_output_config.c
+++ b/lib_dec/ivas_output_config.c
@@ -81,7 +81,11 @@ void ivas_renderer_select(
test();
test();
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
test();
test();
@@ -92,7 +96,11 @@ void ivas_renderer_select(
{
IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
{
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
*renderer_type = RENDERER_BINAURAL_PARAMETRIC;
move16();
@@ -106,7 +114,11 @@ void ivas_renderer_select(
ELSE /* ISM_MODE_DISC */
{
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
*renderer_type = RENDERER_BINAURAL_OBJECTS_TD;
move16();
@@ -127,7 +139,11 @@ void ivas_renderer_select(
*internal_config = output_config;
move16();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
*renderer_type = RENDERER_BINAURAL_PARAMETRIC;
move16();
@@ -144,7 +160,11 @@ void ivas_renderer_select(
move16();
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
*renderer_type = RENDERER_BINAURAL_FASTCONV;
move16();
@@ -199,7 +219,11 @@ void ivas_renderer_select(
*internal_config = output_config;
move16();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
*renderer_type = RENDERER_BINAURAL_PARAMETRIC;
move16();
@@ -215,7 +239,11 @@ void ivas_renderer_select(
*internal_config = transport_config;
move16();
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
test();
test();
diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c
index e27bc063809994fe3b4b035f7e2632c97890831d..f1ac7fa768ce50b738268ccdac0bec351259118b 100644
--- a/lib_dec/ivas_sba_dec.c
+++ b/lib_dec/ivas_sba_dec.c
@@ -185,7 +185,11 @@ ivas_error ivas_sba_dec_reconfigure_fx(
test();
test();
test();
- IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ ) )
{
RENDERER_TYPE renderer_type_new;
Word16 sba_order_internal;
@@ -196,7 +200,11 @@ ivas_error ivas_sba_dec_reconfigure_fx(
/* copy the logic from ivas_renderer_select(), because calling this function has too many side effects that would affect the flushing */
IF( LE_16( ivas_get_sba_num_TCs_fx( ivas_total_brate, sba_order_internal ), 2 ) )
{
- IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) )
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
renderer_type_new = RENDERER_BINAURAL_PARAMETRIC;
move16();
@@ -210,7 +218,11 @@ ivas_error ivas_sba_dec_reconfigure_fx(
ELSE
{
test();
- IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ )
{
renderer_type_new = RENDERER_BINAURAL_FASTCONV;
move16();
@@ -628,6 +640,15 @@ ivas_error ivas_sba_dec_reconfigure_fx(
* TD Decorrelator
*-----------------------------------------------------------------*/
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] != NULL )
+ {
+ IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+#else
IF( st_ivas->hDiracDecBin != NULL )
{
IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
@@ -635,6 +656,7 @@ ivas_error ivas_sba_dec_reconfigure_fx(
return error;
}
}
+#endif
/*-----------------------------------------------------------------*
* CLDFB instances
@@ -784,7 +806,11 @@ void ivas_sba_dec_digest_tc_fx(
ivas_spar_dec_digest_tc_fx( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering );
}
test();
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr )
+#else
IF( st_ivas->hDiracDecBin != NULL && ( st_ivas->hDiracDecBin->useTdDecorr ) )
+#endif
{
Word16 nSamplesLeftForTD, default_frame;
Word32 *decorr_signal[BINAURAL_CHANNELS];
@@ -807,9 +833,17 @@ void ivas_sba_dec_digest_tc_fx(
{
Word16 nSamplesToDecorr = s_min( nSamplesLeftForTD, default_frame ); /*Q0*/
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ IF( st_ivas->hDiracDecBin[0]->hTdDecorr )
+#else
IF( st_ivas->hDiracDecBin->hTdDecorr )
+#endif
{
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ivas_td_decorr_process_fx( st_ivas->hDiracDecBin[0]->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr );
+#else
ivas_td_decorr_process_fx( st_ivas->hDiracDecBin->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr );
+#endif
}
FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c
index fdace42d822ae5e85b084285873d70df63bad336..628a32c2b4e13cf76fede512d857139e57d562d8 100644
--- a/lib_dec/ivas_spar_decoder.c
+++ b/lib_dec/ivas_spar_decoder.c
@@ -1999,7 +1999,11 @@ void ivas_spar_dec_upmixer_sf_fx(
test();
test();
test();
- IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) &&
+ IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#endif
+ ) ) &&
!( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) )
{
Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state-6*/
diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h
index cf01ce54fcb68678e8891aec18b491652f22bd0d..2d71508f78e631b3339ba9507add975e85a47d73 100644
--- a/lib_dec/ivas_stat_dec.h
+++ b/lib_dec/ivas_stat_dec.h
@@ -40,6 +40,7 @@
#include "stat_dec.h"
#include "ivas_stat_com.h"
#include "ivas_stat_rend.h"
+#include "isar_stat.h"
/*----------------------------------------------------------------------------------*
@@ -859,6 +860,7 @@ typedef struct renderer_struct
} ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE;
+#ifndef SPLIT_REND_WITH_HEAD_ROT
/* Fastconv binaural data structure */
typedef struct ivas_binaural_rendering_struct
{
@@ -882,8 +884,40 @@ typedef struct ivas_binaural_rendering_struct
REVERB_STRUCT_HANDLE hReverb;
} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE;
+#endif
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*----------------------------------------------------------------------------------*
+ * IVAS decoder specific ISAR wrapper structures
+ *----------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+
+} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE;
+
+typedef struct
+{
+ Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ IVAS_AUDIO_CONFIG config;
+
+} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE;
+
+typedef struct
+{
+ ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/
+ ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/
+ SPLIT_REND_WRAPPER splitrend;
+ ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/
+ Word16 numTdSamplesPerChannelCached;
+
+} ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE;
+#endif
+
/*----------------------------------------------------------------------------------*
* MASA decoder structures
*----------------------------------------------------------------------------------*/
@@ -1029,7 +1063,9 @@ typedef struct decoder_config_structure
int16_t Opt_tsm; /* indicates whether time scaling modification is activated */
IVAS_RENDER_FRAMESIZE render_framesize;
int16_t Opt_delay_comp; /* flag indicating delay compensation active */
-
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ int16_t Opt_Limiter;
+#endif
} DECODER_CONFIG, *DECODER_CONFIG_HANDLE;
@@ -1106,7 +1142,11 @@ typedef struct Decoder_Struct
BINAURAL_RENDERER_HANDLE hBinRenderer; /* fastconv binaural renderer handle */
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; /* Time domain binaural object renderer handle */
TDREND_HRFILT_FiltSet_t *hHrtfTD; /* pointer to HRTF data for TD renderer */
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; /* parametric binaural renderer handle */
+#else
DIRAC_DEC_BIN_HANDLE hDiracDecBin; /* parametric binaural renderer handle */
+#endif
LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; /* MC LS configuration convertion handle */
EFAP_HANDLE hEFAPdata; /* EFAP structure */
VBAP_HANDLE hVBAPdata; /* VBAP structure */
@@ -1130,6 +1170,10 @@ typedef struct Decoder_Struct
int16_t flag_omasa_brate;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */
+ BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1];
+#endif
/* JBM module */
DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */
diff --git a/lib_isar/isar_MSPred.c b/lib_isar/isar_MSPred.c
new file mode 100644
index 0000000000000000000000000000000000000000..4dea48a9ba5cc914dfb47255aa39d406c03f014c
--- /dev/null
+++ b/lib_isar/isar_MSPred.c
@@ -0,0 +1,550 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "options.h"
+#include
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_lcld_rom_tables.h"
+#include "isar_lcld_prot.h"
+#include "isar_prot.h"
+#include "wmc_auto.h"
+#include "basop_util.h"
+#include "enh64.h"
+#include
+/*-------------------------------------------------------------------*
+ * Function _round()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static int32_t _round(
+ float val )
+{
+ return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) );
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function quantPhase()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 quantPhase_fx(
+ Word32 phase,
+ Word16 exp ) // i:31?
+{
+ Word32 phaseQ;
+
+ // phaseQ = _round(phase * PHASE_QUANT_FACTOR);
+ phaseQ = L_shr_r( Mpy_32_32( phase, PHASE_QUANT_FACTOR_FX_Q29 ), 29 - exp ); // Q60
+ if ( phaseQ == PHASE_MAX_VAL )
+ {
+ phaseQ = PHASE_MIN_VAL;
+ }
+ return phaseQ;
+}
+
+int32_t quantPhase(
+ float phase )
+{
+ int32_t phaseQ;
+
+ phaseQ = _round( phase * PHASE_QUANT_FACTOR );
+ if ( phaseQ == PHASE_MAX_VAL )
+ {
+ phaseQ = PHASE_MIN_VAL;
+ }
+ return phaseQ;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function cplxmult()
+ *
+ *
+ *-------------------------------------------------------------------*/
+void cplxmult_fx(
+ Word32 *pr1,
+ Word32 *pi1,
+ Word32 r2,
+ Word32 i2 )
+{
+ Word32 r1 = *pr1, i1 = *pi1;
+
+ *pr1 = L_sub( Mpy_32_32( r1, r2 ), Mpy_32_32( i1, i2 ) );
+ *pi1 = L_add( Mpy_32_32( r1, i2 ), Mpy_32_32( i1, r2 ) );
+
+ return;
+}
+void cplxmult(
+ float *pr1,
+ float *pi1,
+ float r2,
+ float i2 )
+{
+ float r1 = *pr1, i1 = *pi1;
+
+ *pr1 = r1 * r2 - i1 * i2;
+ *pi1 = r1 * i2 + i1 * r2;
+
+ return;
+}
+/*-------------------------------------------------------------------*
+ * Function requantPhase()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 requantPhase(
+ Word32 phaseQ )
+{
+
+ IF( GE_32( phaseQ, PHASE_MAX_VAL ) )
+ {
+ phaseQ = L_add( phaseQ, PHASE_MAX_VAL );
+ phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) );
+ phaseQ = L_sub( phaseQ, PHASE_MAX_VAL );
+ }
+ ELSE IF( LT_32( phaseQ, PHASE_MIN_VAL ) )
+ {
+ phaseQ = L_sub( phaseQ, PHASE_MAX_VAL );
+ phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) );
+ phaseQ = L_add( phaseQ, PHASE_MAX_VAL );
+ IF( EQ_32( phaseQ, PHASE_MAX_VAL ) )
+ {
+ phaseQ = PHASE_MIN_VAL;
+ move32();
+ }
+ }
+
+ return phaseQ;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function quantPred()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 quantPred_fx(
+ const Word32 pred,
+ Word16 exp ) // i:Q31
+{
+ // int32_t predQ = _round(pred * PRED_QUANT_FACTOR);
+ Word32 predQ = W_round32_s( W_shl( W_mult_32_32( pred, (Word32) PRED_QUANT_FACTOR ), exp ) );
+ predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ;
+ predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ;
+
+ return predQ;
+}
+int32_t quantPred(
+ const float pred )
+{
+ int32_t predQ = _round( pred * PRED_QUANT_FACTOR );
+ predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ;
+ predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ;
+
+ return predQ;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function dequantPhase()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+float dequantPhase(
+ const int32_t phaseQ )
+{
+ return (float) phaseQ / PHASE_QUANT_FACTOR;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function dequantPred()
+ *
+ *
+ *-------------------------------------------------------------------*/
+Word32 dequantPred_fx( Word32 predQ )
+{
+ if ( predQ == 12 )
+ {
+ return MAX_32;
+ }
+ Word16 tmp_e;
+ Word32 tmp, value;
+ if ( predQ == 0 )
+ {
+ return predQ;
+ }
+ tmp = BASOP_Util_Divide3216_Scale( predQ, PRED_QUANT_FACTOR_FX, &tmp_e );
+ value = L_shl( tmp, sub( 31, negate( add( 1, tmp_e ) ) ) ); // Q31
+ return value;
+}
+float dequantPred( int32_t predQ )
+{
+ return (float) predQ / PRED_QUANT_FACTOR;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function PrepEncode()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 PrepEncode(
+ Word32 *piQuant,
+ const Word32 *piMSFlags,
+ const Word32 numBands )
+{
+ Word32 b, numMSBands;
+ numMSBands = 0;
+ move32();
+
+ FOR( b = 0; b < numBands; b++ )
+ {
+ IF( piMSFlags[b] )
+ {
+ piQuant[numMSBands++] = piQuant[b];
+ move32();
+ }
+ }
+
+ FOR( b = numMSBands; b < numBands; b++ )
+ {
+ piQuant[b] = 0;
+ move32();
+ }
+
+ return numMSBands;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function EncodePhase()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void EncodePhase(
+ Word32 *phaseQuant,
+ const Word32 numMSBands,
+ const Word32 diffDim )
+{
+ Word32 b;
+
+ IF( GT_32( diffDim, 0 ) )
+ {
+ Word32 tmp1, tmp2;
+ tmp1 = phaseQuant[0];
+ move32();
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ tmp2 = phaseQuant[b];
+ move32();
+ phaseQuant[b] = L_sub( phaseQuant[b], tmp1 );
+ tmp1 = tmp2;
+ move32();
+ }
+ }
+
+ IF( GT_32( diffDim, 1 ) )
+ {
+ Word32 tmp1, tmp2;
+ tmp1 = phaseQuant[1];
+ move32();
+ FOR( b = 2; b < numMSBands; b++ )
+ {
+ tmp2 = phaseQuant[b];
+ move32();
+ phaseQuant[b] = L_sub( phaseQuant[b], tmp1 );
+ tmp1 = tmp2;
+ move32();
+ }
+ }
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ phaseQuant[b] = requantPhase( phaseQuant[b] );
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function DecodePhase()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void DecodePhase(
+ Word32 *phaseQuant,
+ const Word32 numMSBands,
+ const Word32 diffDim )
+{
+ Word32 b;
+
+ IF( GT_32( diffDim, 1 ) )
+ {
+ FOR( b = 2; b < numMSBands; b++ )
+ {
+ phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] );
+ move32();
+ }
+ }
+
+ IF( GT_32( diffDim, 0 ) )
+ {
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] );
+ move32();
+ }
+ }
+
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ phaseQuant[b] = requantPhase( phaseQuant[b] );
+ move32();
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function EncodePredCoef()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 EncodePredCoef(
+ Word32 *predQuant,
+ const Word32 numMSBands )
+{
+ Word32 b, tmp1, tmp2;
+
+ tmp1 = predQuant[0];
+ move32();
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ tmp2 = predQuant[b];
+ move32();
+ predQuant[b] = L_sub( predQuant[b], tmp1 );
+ tmp1 = tmp2;
+ move32();
+ }
+
+ return numMSBands;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function DecodePredCoef()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void DecodePredCoef(
+ Word32 *phaseQuant,
+ const Word32 numMSBands )
+{
+ Word32 b;
+
+ FOR( b = 1; b < numMSBands; b++ )
+ {
+ phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] );
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function CountMSBits()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 CountMSBits(
+ Word32 iNumBands,
+ const Word32 iMSMode,
+ const Word32 *piMSFlags,
+ const Word32 *piLRPhaseDiff,
+ const Word32 *piMSPredCoef )
+{
+ Word32 iBitsWritten = 0;
+ move32();
+ Word32 b;
+ Word32 anyNonZero;
+ Word32 iNumMSBands = 0;
+ move32();
+ Word32 piPhaseCopy[MAX_BANDS_48];
+ Word32 piPredCopy[MAX_BANDS_48];
+
+ FOR( b = 0; b < MAX_BANDS_48; b++ )
+ {
+ piPhaseCopy[b] = 0;
+ move32();
+ piPredCopy[b] = 0;
+ move32();
+ }
+
+ iBitsWritten = L_add( iBitsWritten, 2 ); /* iMSMode */
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ iNumMSBands = L_add( iNumMSBands, NE_32( piMSFlags[b], 0 ) );
+ }
+
+ IF( EQ_32( iNumMSBands, 0 ) )
+ {
+ return iBitsWritten;
+ }
+
+ IF( LT_32( iNumMSBands, iNumBands ) )
+ {
+ iBitsWritten = L_add( iBitsWritten, iNumBands ); /* piMSFlags */
+ }
+
+ IF( LT_32( iMSMode, 3 ) )
+ {
+ return iBitsWritten;
+ }
+
+ /* prepare arrays for coding evaluation */
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ piPhaseCopy[b] = piLRPhaseDiff[b];
+ move32();
+ piPredCopy[b] = piMSPredCoef[b];
+ move32();
+ }
+
+ /* Differential Coding of Phase Data*/
+ PrepEncode( piPhaseCopy, piMSFlags, iNumBands );
+ PrepEncode( piPredCopy, piMSFlags, iNumBands );
+ EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM );
+ EncodePredCoef( piPredCopy, iNumMSBands );
+
+ iBitsWritten = L_add( iBitsWritten, 1 ); /* iMSPredAll */
+ anyNonZero = 0; /* phase */
+ move32();
+ FOR( b = 0; b < iNumMSBands; b++ )
+ {
+ IF( NE_32( piPhaseCopy[b], 0 ) )
+ {
+ anyNonZero = 1;
+ move32();
+ BREAK;
+ }
+ }
+ iBitsWritten = L_add( iBitsWritten, 1 ); /*anyNonZero Phase*/
+ IF( anyNonZero )
+ {
+ iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS );
+ FOR( b = 1; b < iNumMSBands; b++ )
+ {
+ Word32 tabIdx = L_sub( piPhaseCopy[b], ENV_DELTA_MIN );
+ iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ }
+ }
+ anyNonZero = 0; /* prediction */
+ move32();
+ FOR( b = 0; b < iNumMSBands; b++ )
+ {
+ IF( NE_32( piPredCopy[b], 0 ) )
+ {
+ anyNonZero = 1;
+ move32();
+ break;
+ }
+ }
+
+ iBitsWritten = L_add( iBitsWritten, 1 ); /* any nonZero Pred */
+ IF( anyNonZero )
+ {
+ iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS );
+ FOR( b = 1; b < iNumMSBands; b++ )
+ {
+ Word32 tabIdx = L_sub( piPredCopy[b], ENV_DELTA_MIN );
+ iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ }
+ }
+
+ return iBitsWritten;
+}
+
+
+#ifdef DEBUG_WRITE_MS_PRED
+void writeMSPred(
+ int32_t *phaseQuant,
+ int32_t *predQuant,
+ int32_t MSMode,
+ int32_t numMSBands,
+ int32_t numBands,
+ void *fid,
+ int32_t *piMsFlags )
+{
+ int32_t b;
+
+ fid = (FILE *) fid;
+ fprintf( fid, "%d %d", MSMode, numMSBands );
+ for ( b = 0; b < numMSBands; b++ )
+ {
+ fprintf( fid, " %d", phaseQuant[b] );
+ }
+ for ( b = numMSBands; b < numBands; b++ )
+ {
+ fprintf( fid, " %d", 0 );
+ }
+ for ( b = 0; b < numMSBands; b++ )
+ {
+ fprintf( fid, " %d", predQuant[b] );
+ }
+ for ( b = numMSBands; b < numBands; b++ )
+ {
+ fprintf( fid, " %d", 0 );
+ }
+ for ( b = 0; b < numBands; b++ )
+ {
+ fprintf( fid, " %d", piMsFlags[b] );
+ }
+ fprintf( fid, "\n" );
+
+ return;
+}
+#endif
+#endif
diff --git a/lib_isar/isar_NoiseGen.c b/lib_isar/isar_NoiseGen.c
new file mode 100644
index 0000000000000000000000000000000000000000..a61f26fc201739e17afcb19d44c5a1657c52c717
--- /dev/null
+++ b/lib_isar/isar_NoiseGen.c
@@ -0,0 +1,58 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "prot.h"
+#include "isar_lcld_prot.h"
+#include "wmc_auto.h"
+
+
+/*------------------------------------------------------------------------------------------*
+ * Function DeleteNoiseGen()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void DeleteNoiseGen( NoiseGen *psNoiseGen )
+{
+ free( psNoiseGen->pfNoiseBuffer );
+ free( psNoiseGen );
+
+ return;
+}
+
+extern float GetNoise( NoiseGen *psNoiseGen );
+extern Word32 GetNoise_fx( NoiseGen *psNoiseGen );
+#endif
diff --git a/lib_isar/isar_PerceptualModel.c b/lib_isar/isar_PerceptualModel.c
new file mode 100644
index 0000000000000000000000000000000000000000..85864ae0dcc0dbb8dcbf4b9446c2183e2a642239
--- /dev/null
+++ b/lib_isar/isar_PerceptualModel.c
@@ -0,0 +1,469 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_lcld_prot.h"
+#include "prot.h"
+#include "isar_lcld_rom_tables.h"
+#include
+#include "wmc_auto.h"
+
+
+/*------------------------------------------------------------------------------------------*
+ * Local constants
+ *------------------------------------------------------------------------------------------*/
+#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 )
+#define PERCEPTUAL_MODEL_SCALE ( 64 )
+#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 )
+#define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 )
+#define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 )
+#define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 )
+
+/*------------------------------------------------------------------------------------------*
+ * Function LogAdd()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+static inline Word16 LogAdd_fx(
+ const Word16 iVal1,
+ const Word16 iVal2 )
+{
+ Word16 iRetVal;
+
+ IF( iVal1 > iVal2 )
+ {
+ iRetVal = sub( iVal1, iVal2 );
+ move16();
+ iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 );
+ move16();
+ iRetVal = add( iVal1, c_aiLogAddTable_fx[iRetVal] );
+ move16();
+ }
+ ELSE
+ {
+ iRetVal = sub( iVal2, iVal1 );
+ move16();
+ iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 );
+ move16();
+ iRetVal = add( iVal2, c_aiLogAddTable_fx[iRetVal] );
+ move16();
+ }
+
+ return iRetVal;
+}
+/*------------------------------------------------------------------------------------------*
+ * Function LogAdd()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+static inline int32_t LogAdd(
+ const int32_t iVal1,
+ const int32_t iVal2 )
+{
+ int32_t iRetVal;
+
+ if ( iVal1 > iVal2 )
+ {
+ iRetVal = iVal1 - iVal2;
+ iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 );
+ iRetVal = iVal1 + c_aiLogAddTable[iRetVal];
+ }
+ else
+ {
+ iRetVal = iVal2 - iVal1;
+ iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 );
+ iRetVal = iVal2 + c_aiLogAddTable[iRetVal];
+ }
+
+ return iRetVal;
+}
+/*------------------------------------------------------------------------------------------*
+ * Function PerceptualModel()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void PerceptualModel_fx(
+ const Word32 iMaxQuantBands,
+ const Word32 *piRMSEnvelope,
+ Word32 *piExcitation,
+ Word32 *piSMR )
+{
+ Word16 n;
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 iSLOffset;
+
+ piExcitation[n] = shl( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ); // shift instead of multiplying by PERCEPTUAL_MODEL_SCALE
+ move16();
+ /* Calculate sensation level offset */
+ iSLOffset = (Word16) extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) );
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+ move16();
+ /* Offset envelope by sensation level offset */
+ piExcitation[n] = sub( extract_l( piExcitation[n] ), iSLOffset );
+ move16();
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ }
+
+ /* Spread excitation function */
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 k;
+ const Word16 *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48];
+ move16();
+ piSMR[n] = add( extract_l( piExcitation[n] ), piSpread[n] );
+ move16();
+ FOR( k = 0; k < iMaxQuantBands; k++ )
+ {
+ IF( NE_16( k, n ) )
+ {
+ piSMR[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR[n] ), add( extract_l( piExcitation[k] ), piSpread[k] ) ) );
+ move16();
+ }
+ }
+ }
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ piSMR[n] = shl( sub( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_SCALE_SHIFT );
+ move16();
+ }
+
+ return;
+}
+/*------------------------------------------------------------------------------------------*
+ * Function PerceptualModel()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void PerceptualModel(
+ const int32_t iMaxQuantBands,
+ const int32_t *piRMSEnvelope,
+ int32_t *piExcitation,
+ int32_t *piSMR )
+{
+ int32_t n;
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t iSLOffset;
+
+ piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n];
+
+ /* Calculate sensation level offset */
+ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT;
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+
+ /* Offset envelope by sensation level offset */
+ piExcitation[n] -= iSLOffset;
+
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ }
+
+ /* Spread excitation function */
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t k;
+ const int32_t *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48];
+ piSMR[n] = piExcitation[n] + piSpread[n];
+ for ( k = 0; k < iMaxQuantBands; k++ )
+ {
+ if ( k != n )
+ {
+ piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] );
+ }
+ }
+ }
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n];
+ }
+
+ return;
+}
+/*------------------------------------------------------------------------------------------*
+ * Function PerceptualModelStereo()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void PerceptualModelStereo(
+ const int32_t iMaxQuantBands,
+ const int32_t *piMSFlags,
+ const int32_t *piRMSEnvelope0,
+ const int32_t *piRMSEnvelope1,
+ int32_t *piExcitation0,
+ int32_t *piExcitation1,
+ int32_t *piSMR0,
+ int32_t *piSMR1 )
+{
+ int32_t n;
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t iMaxRMSEnv;
+ int32_t iSLOffset;
+
+ iMaxRMSEnv = piRMSEnvelope0[n];
+
+ piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */
+
+ /* Calculate sensation level offset */
+ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT;
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+
+ /* Offset envelope by sensation level offset */
+ piExcitation0[n] -= iSLOffset;
+
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ }
+
+ /* Spread excitation function */
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t k;
+ const int32_t *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48];
+ piSMR0[n] = piExcitation0[n] + piSpread[n];
+ for ( k = 0; k < iMaxQuantBands; k++ )
+ {
+ if ( k != n )
+ {
+ piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] );
+ }
+ }
+ }
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t iMaxRMSEnv;
+ int32_t iSLOffset;
+
+ iMaxRMSEnv = piRMSEnvelope1[n];
+
+ piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */
+
+ /* Calculate sensation level offset */
+ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT;
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+
+ /* Offset envelope by sensation level offset */
+ piExcitation1[n] -= iSLOffset;
+
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ }
+
+ /* Spread excitation function */
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ int32_t k;
+ const int32_t *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48];
+ piSMR1[n] = piExcitation1[n] + piSpread[n];
+ for ( k = 0; k < iMaxQuantBands; k++ )
+ {
+ if ( k != n )
+ {
+ piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] );
+ }
+ }
+ }
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ if ( piMSFlags[n] == 1 )
+ {
+ piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n];
+ piSMR1[n] = piSMR0[n];
+ }
+ }
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n];
+ }
+
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT;
+ piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n];
+ }
+
+ return;
+}
+void PerceptualModelStereo_fx(
+ const Word32 iMaxQuantBands,
+ const Word32 *piMSFlags,
+ const Word32 *piRMSEnvelope0,
+ const Word32 *piRMSEnvelope1,
+ Word32 *piExcitation0,
+ Word32 *piExcitation1,
+ Word32 *piSMR0,
+ Word32 *piSMR1 )
+{
+ Word16 n;
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 iMaxRMSEnv;
+ Word16 iSLOffset;
+
+ iMaxRMSEnv = extract_l( piRMSEnvelope0[n] );
+ move16();
+ piExcitation0[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope0[n] */
+ move16();
+ /* Calculate sensation level offset */
+ iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation0[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) );
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+ move16();
+ /* Offset envelope by sensation level offset */
+ piExcitation0[n] = sub( extract_l( piExcitation0[n] ), iSLOffset );
+ move16();
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ }
+
+ /* Spread excitation function */
+ for ( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 k;
+ const Word16 *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48];
+ move16();
+ piSMR0[n] = add( extract_l( piExcitation0[n] ), piSpread[n] );
+ move16();
+ FOR( k = 0; k < iMaxQuantBands; k++ )
+ {
+ IF( NE_16( k, n ) )
+ {
+ piSMR0[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR0[n] ), add( extract_l( piExcitation0[k] ), piSpread[k] ) ) );
+ move16();
+ }
+ }
+ }
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 iMaxRMSEnv;
+ Word16 iSLOffset;
+
+ iMaxRMSEnv = extract_l( piRMSEnvelope1[n] );
+ move16();
+ piExcitation1[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope1[n] */
+ move16();
+ /* Calculate sensation level offset */
+ iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation1[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) );
+ // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0;
+ move16();
+ /* Offset envelope by sensation level offset */
+ piExcitation1[n] = sub( extract_l( piExcitation1[n] ), iSLOffset );
+ move16();
+ /* Convert to loudness domain (x^0.3) */
+ piExcitation1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ }
+
+ /* Spread excitation function */
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ Word16 k;
+ const Word16 *piSpread;
+
+ piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48];
+ move16();
+ piSMR1[n] = add( extract_l( piExcitation1[n] ), piSpread[n] );
+ move16();
+ FOR( k = 0; k < iMaxQuantBands; k++ )
+ {
+ IF( NE_16( k, n ) )
+ {
+ piSMR1[n] = LogAdd_fx( extract_l( piSMR1[n] ), add( extract_l( piExcitation1[k] ), piSpread[k] ) );
+ move16();
+ }
+ }
+ }
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ IF( EQ_16( extract_l( piMSFlags[n] ), 1 ) )
+ {
+ piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n];
+ move16();
+ piSMR1[n] = piSMR0[n];
+ move16();
+ }
+ }
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ piSMR0[n] = sub( add( shl( extract_l( piRMSEnvelope0[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR0[n] ) );
+ move16();
+ }
+
+ FOR( n = 0; n < iMaxQuantBands; n++ )
+ {
+ piSMR1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) );
+ move16();
+ piSMR1[n] = sub( add( shl( extract_l( piRMSEnvelope1[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR1[n] ) );
+ move16();
+ }
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_PredDecoder.c b/lib_isar/isar_PredDecoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..3fa9ec87762ae1e35af08333c0ec6f972830abe8
--- /dev/null
+++ b/lib_isar/isar_PredDecoder.c
@@ -0,0 +1,496 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "prot.h"
+#include "isar_prot.h"
+#include "isar_lcld_prot.h"
+#include "isar_lcld_rom_tables.h"
+#include "wmc_auto.h"
+#include "basop_mpy.h"
+
+/*-------------------------------------------------------------------*
+ * Function CreatePredictionDecoder()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error CreatePredictionDecoder_fx(
+ PredictionDecoder **psPredictionDecoder_out,
+ const Word32 iChannels,
+ const Word32 iNumBlocks )
+{
+ Word16 n;
+ Word16 m;
+ PredictionDecoder *psPredictionDecoder = NULL;
+
+ IF( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ psPredictionDecoder->iChannels = iChannels;
+ move32();
+ psPredictionDecoder->iNumBlocks = iNumBlocks;
+ move32();
+ psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks;
+ move32();
+ psPredictionDecoder->iSubSetId = 0;
+ move32();
+ /* PLC_IMPROVEMENT */
+ IF( ( psPredictionDecoder->ppiDecodingFailedPrev = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiDecodingFailed = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiDecodingUnresolved = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 k;
+ IF( ( psPredictionDecoder->ppiDecodingUnresolved[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiDecodingFailed[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiDecodingFailedPrev[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ FOR( k = 0; k < LCLD_MAX_NUM_PRED_SUBSETS; k++ )
+ {
+ psPredictionDecoder->ppiDecodingUnresolved[n][k] = 0;
+ move32();
+ psPredictionDecoder->ppiDecodingFailed[n][k] = 0;
+ move32();
+ psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0;
+ move32();
+ }
+ }
+ IF( ( psPredictionDecoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+
+ FOR( n = 0; n < psPredictionDecoder->iChannels; n++ )
+ {
+ psPredictionDecoder->piPredChanEnable[n] = 0;
+ move32();
+ IF( ( psPredictionDecoder->ppiPredBandEnable[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ FOR( m = 0; m < LCLD_BANDS; m++ )
+ {
+ psPredictionDecoder->ppiPredBandEnable[n][m] = 0;
+ move32();
+ }
+ IF( ( psPredictionDecoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) );
+ }
+ IF( ( psPredictionDecoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) );
+ }
+ FOR( m = 0; m < LCLD_BANDS; m++ )
+ {
+ psPredictionDecoder->ppfPredStateReal_fx[n][m] = 0;
+ move32();
+ psPredictionDecoder->ppfPredStateImag_fx[n][m] = 0;
+ move32();
+ }
+ }
+
+ /* pre-define these tables? */
+
+ FOR( n = 0; n < ( 1 << PRED_QUNAT_FILTER_MAG_BITS ); n++ )
+ {
+ psPredictionDecoder->pfMagLUT_fx[n] = c_pfMagLUT[n]; /* Q31 */
+ move32();
+ }
+
+ FOR( n = 0; n < ( 1 << PRED_QUANT_FILTER_PHASE_BITS ); n++ )
+ {
+ psPredictionDecoder->pfP2RRealLUT_fx[n] = c_pfP2RRealLUT[n]; /* Q31 */
+ move32();
+ psPredictionDecoder->pfP2RImagLUT_fx[n] = c_pfP2RImagLUT[n]; /* Q31 */
+ move32();
+ }
+
+ *psPredictionDecoder_out = psPredictionDecoder;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * Function DeletePredictionDecoder()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void DeletePredictionDecoder_fx(
+ PredictionDecoder *psPredictionDecoder )
+{
+ Word32 n;
+
+ FOR( n = 0; n < psPredictionDecoder->iChannels; n++ )
+ {
+ free( psPredictionDecoder->ppiPredBandEnable[n] );
+ free( psPredictionDecoder->ppfA1Real_fx[n] );
+ free( psPredictionDecoder->ppfA1Imag_fx[n] );
+ free( psPredictionDecoder->ppiA1Mag[n] );
+ free( psPredictionDecoder->ppiA1Phase[n] );
+ free( psPredictionDecoder->ppfPredStateReal_fx[n] );
+ free( psPredictionDecoder->ppfPredStateImag_fx[n] );
+ free( psPredictionDecoder->ppiDecodingUnresolved[n] );
+ free( psPredictionDecoder->ppiDecodingFailed[n] );
+ free( psPredictionDecoder->ppiDecodingFailedPrev[n] );
+ }
+ free( psPredictionDecoder->piPredChanEnable );
+ free( psPredictionDecoder->ppiPredBandEnable );
+ free( psPredictionDecoder->ppfA1Real_fx );
+ free( psPredictionDecoder->ppfA1Imag_fx );
+ free( psPredictionDecoder->ppiA1Mag );
+ free( psPredictionDecoder->ppiA1Phase );
+ free( psPredictionDecoder->ppfPredStateReal_fx );
+ free( psPredictionDecoder->ppfPredStateImag_fx );
+ /* PLC_IMPROVEMENT */
+ free( psPredictionDecoder->ppiDecodingUnresolved );
+ free( psPredictionDecoder->ppiDecodingFailed );
+ free( psPredictionDecoder->ppiDecodingFailedPrev );
+
+ free( psPredictionDecoder );
+ psPredictionDecoder = NULL;
+
+ return;
+}
+/*-------------------------------------------------------------------*
+ * Function ReadPredictors()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 ReadPredictors_fx(
+ PredictionDecoder *psPredictionDecoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word16 iBitsRead = 0;
+ Word32 c;
+ Word32 b;
+ Word16 iNumPredBandBits = 6;
+ const Word16 iSubSetBits = ( GT_32( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 );
+ move16();
+ move16();
+ move16();
+
+ psPredictionDecoder->iNumSubSets = L_add( ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ), 1 );
+ iBitsRead = add( iBitsRead, iSubSetBits );
+
+ IF( GT_32( psPredictionDecoder->iNumSubSets, 1 ) )
+ {
+ psPredictionDecoder->iSubSetId = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits );
+ iBitsRead = add( iBitsRead, iSubSetBits );
+ iNumPredBandBits = ( GE_32( psPredictionDecoder->iNumSubSets, 4 ) ? 4 : 5 );
+ move16();
+ }
+ ELSE
+ {
+ psPredictionDecoder->iSubSetId = 0;
+ move32();
+ }
+ FOR( c = 0; c < psPredictionDecoder->iChannels; c++ )
+ {
+ psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets );
+ move32();
+ iBitsRead = add( iBitsRead, (Word16) psPredictionDecoder->iNumSubSets );
+
+ IF( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) )
+ {
+ Word32 b0 = psPredictionDecoder->iSubSetId;
+ Word32 bstep = psPredictionDecoder->iNumSubSets;
+ Word32 iNumPredBands;
+ move32();
+ move32();
+
+ FOR( b = b0; b < LCLD_BANDS; b = L_add( b, bstep ) )
+ {
+ psPredictionDecoder->ppiPredBandEnable[c][b] = 0;
+ move32();
+ }
+ iNumPredBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iNumPredBandBits );
+ iBitsRead = add( iBitsRead, iNumPredBandBits );
+ iNumPredBands = L_add( L_mult0( (Word16) iNumPredBands, (Word16) psPredictionDecoder->iNumSubSets ), b0 );
+
+ FOR( b = b0; b < iNumPredBands; b = L_add( b, bstep ) )
+ {
+ psPredictionDecoder->ppiPredBandEnable[c][b] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = add( iBitsRead, 1 );
+
+ IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) )
+ {
+ Word32 iA1Mag;
+ Word32 iA1Phase;
+ Word32 fA1Real;
+ Word32 fA1Imag;
+ iA1Mag = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS );
+ iBitsRead = add( iBitsRead, PRED_QUNAT_FILTER_MAG_BITS );
+ iA1Phase = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS );
+ iBitsRead = add( iBitsRead, PRED_QUANT_FILTER_PHASE_BITS );
+
+ psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag;
+ move32();
+ psPredictionDecoder->ppiA1Phase[c][b] = L_add( iA1Phase, PRED_QUANT_FILTER_PHASE_MIN );
+ move32();
+
+ fA1Real = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RRealLUT_fx[iA1Phase] ); /* Q31 */
+ fA1Imag = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RImagLUT_fx[iA1Phase] ); /* Q31 */
+
+ psPredictionDecoder->ppfA1Real_fx[c][b] = fA1Real; /* Q31 */
+ move32();
+ psPredictionDecoder->ppfA1Imag_fx[c][b] = fA1Imag; /* Q31 */
+ move32();
+ }
+ }
+ }
+ }
+
+ /* disable any inactive prediction bands */
+ FOR( c = 0; c < psPredictionDecoder->iChannels; c++ )
+ {
+ Word32 set;
+ FOR( set = 0; set < psPredictionDecoder->iNumSubSets; set++ )
+ {
+ IF( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) )
+ {
+ FOR( b = set; b < LCLD_BANDS; b = L_add( b, psPredictionDecoder->iNumSubSets ) )
+ {
+ psPredictionDecoder->ppiPredBandEnable[c][b] = 0;
+ move32();
+ }
+ }
+ }
+ }
+
+ return iBitsRead;
+}
+/* PLC_IMPROVEMENT */
+void SetDecodingPassed( PredictionDecoder *psPredictionDecoder )
+{
+ int32_t n, ch;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ psPredictionDecoder->ppiDecodingFailed[ch][n] = 0;
+ }
+ }
+}
+int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder )
+{
+ int32_t n, ch;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ if ( psPredictionDecoder->ppiDecodingUnresolved[ch][n] == 1 )
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+void UpdateDecodingFailedStatus( PredictionDecoder *psPredictionDecoder )
+{
+ int32_t n, ch;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = psPredictionDecoder->ppiDecodingFailed[ch][n];
+ }
+ }
+}
+
+void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder )
+{
+ int32_t n, ch;
+
+ int32_t iCurrentSubSet = psPredictionDecoder->iSubSetId;
+
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ /* Prediction data always available for current subset */
+ psPredictionDecoder->ppiDecodingUnresolved[ch][iCurrentSubSet] = 0;
+
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ int32_t iSubSetActive = get_bit( psPredictionDecoder->piPredChanEnable[ch], n );
+ if ( iSubSetActive == 0 )
+ {
+ /* Prediction information available inactive subsets (e.g. no Prediction) */
+ psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 0;
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------*
+ * Function ApplyInversePredictors()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ApplyInversePredictors_fx(
+ PredictionDecoder *psPredictionDecoder,
+ Word32 ***pppfReal,
+ Word32 ***pppfImag )
+{
+ Word32 c;
+ FOR( c = 0; c < psPredictionDecoder->iChannels; c++ )
+ {
+ IF( GT_32( psPredictionDecoder->piPredChanEnable[c], 0 ) )
+ {
+ Word32 b;
+ FOR( b = 0; b < LCLD_BANDS; b++ )
+ {
+ IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) )
+ {
+ Word32 n;
+ Word32 fA1Real;
+ Word32 fA1Imag;
+ Word32 fPrevReal = 0;
+ move32();
+ Word32 fPrevImag = 0;
+ move32();
+ Word32 iSubset = b % psPredictionDecoder->iNumSubSets;
+
+ IF( NE_32( iSubset, psPredictionDecoder->iSubSetId ) )
+ {
+ fPrevReal = psPredictionDecoder->ppfPredStateReal_fx[c][b];
+ move32();
+ fPrevImag = psPredictionDecoder->ppfPredStateImag_fx[c][b];
+ move32();
+ }
+
+ fA1Real = psPredictionDecoder->ppfA1Real_fx[c][b];
+ move32();
+ fA1Imag = psPredictionDecoder->ppfA1Imag_fx[c][b];
+ move32();
+ FOR( n = 0; n < psPredictionDecoder->iNumBlocks; n++ )
+ {
+ Word32 fReal;
+ Word32 fImag;
+
+ fReal = L_add( L_sub( pppfReal[c][n][b], Mpy_32_32( fA1Real, fPrevReal ) ), Mpy_32_32( fA1Imag, fPrevImag ) );
+ fImag = L_sub( L_sub( pppfImag[c][n][b], Mpy_32_32( fA1Real, fPrevImag ) ), Mpy_32_32( fA1Imag, fPrevReal ) );
+
+ pppfReal[c][n][b] = fReal;
+ move32();
+ pppfImag[c][n][b] = fImag;
+ move32();
+
+ fPrevReal = fReal;
+ move32();
+ fPrevImag = fImag;
+ move32();
+ }
+ psPredictionDecoder->ppfPredStateReal_fx[c][b] = fPrevReal;
+ move32();
+ psPredictionDecoder->ppfPredStateImag_fx[c][b] = fPrevImag;
+ move32();
+ }
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_PredEncoder.c b/lib_isar/isar_PredEncoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ca4d7add6a8fe8a17da99df17a3f2d71ed4d232
--- /dev/null
+++ b/lib_isar/isar_PredEncoder.c
@@ -0,0 +1,1215 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "isar_lcld_prot.h"
+#include "isar_lcld_rom_tables.h"
+#include "prot.h"
+#include "isar_prot.h"
+#include "wmc_auto.h"
+#include "prot_fx2.h"
+#include "basop_util.h"
+#include "enh64.h"
+#include "basop32.h"
+
+
+/*-------------------------------------------------------------------*
+ * Function activate_bit()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void activate_bit(
+ Word32 *state,
+ const Word32 bit_id )
+{
+ ( *state ) = L_or( ( *state ), L_shl( 1, extract_l( bit_id ) ) );
+}
+
+/*-------------------------------------------------------------------*
+ * Function deactivate_bit()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static void deactivate_bit(
+ Word32 *state,
+ const Word32 bit_id )
+{
+ ( *state ) = L_and( ( *state ), ~L_shl( 1, extract_l( bit_id ) ) );
+}
+void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder )
+{
+ IF( EQ_32( ++psPredictionEncoder->iSubSetId, psPredictionEncoder->iNumSubSets ) )
+ {
+ psPredictionEncoder->iSubSetId = 0;
+ move32();
+ }
+}
+/*-------------------------------------------------------------------*
+ * Function CreatePredictionEncoder()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error CreatePredictionEncoder_fx(
+ PredictionEncoder **psPredictionEncoder_out,
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ const Word32 iNumSubSets,
+ const Word32 iMaxNumPredBands )
+{
+ Word32 k, n;
+ PredictionEncoder *psPredictionEncoder = NULL;
+
+ IF( ( psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ psPredictionEncoder->iChannels = iChannels;
+ move32();
+ psPredictionEncoder->iNumBlocks = iNumBlocks;
+ move32();
+ psPredictionEncoder->iSubSetId = 0;
+ move32();
+ psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands;
+ move32();
+ psPredictionEncoder->iNumSubSets = iNumSubSets;
+ move32();
+ IF( ( psPredictionEncoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ IF( ( psPredictionEncoder->piNumPredBands = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ FOR( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ psPredictionEncoder->piPredChanEnable[n] = 0;
+ move32();
+ psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly
+ move32();
+ }
+
+ IF( ( psPredictionEncoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->pppfInpBufReal_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->pppfInpBufImag_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfInpPrevReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfInpPrevImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ FOR( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ IF( ( psPredictionEncoder->ppiPredBandEnable[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->pppfInpBufReal_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * LCLD_PRED_WIN_LEN ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->pppfInpBufImag_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * LCLD_PRED_WIN_LEN ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ FOR( k = 0; k < LCLD_PRED_WIN_LEN; k++ )
+ {
+ IF( ( psPredictionEncoder->pppfInpBufReal_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->pppfInpBufImag_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set32_fx( psPredictionEncoder->pppfInpBufReal_fx[n][k], 0, LCLD_BANDS );
+ set32_fx( psPredictionEncoder->pppfInpBufImag_fx[n][k], 0, LCLD_BANDS );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set32_fx( psPredictionEncoder->ppfPredStateReal_fx[n], 0, LCLD_BANDS );
+ set32_fx( psPredictionEncoder->ppfPredStateImag_fx[n], 0, LCLD_BANDS );
+
+ IF( ( psPredictionEncoder->ppfInpPrevReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfInpPrevImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ set32_fx( psPredictionEncoder->ppfInpPrevReal_fx[n], 0, LCLD_BANDS );
+ set32_fx( psPredictionEncoder->ppfInpPrevImag_fx[n], 0, LCLD_BANDS );
+
+ IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set32_fx( psPredictionEncoder->ppfPredStateRealTmp_fx[n], 0, LCLD_BANDS );
+ set32_fx( psPredictionEncoder->ppfPredStateImagTmp_fx[n], 0, LCLD_BANDS );
+ FOR( k = 0; k < LCLD_BANDS; k++ )
+ {
+ psPredictionEncoder->ppiPredBandEnable[n][k] = 0;
+ move32();
+ psPredictionEncoder->ppfA1Real_fx[n][k] = 0;
+ move32();
+ psPredictionEncoder->ppfA1Imag_fx[n][k] = 0;
+ move32();
+ }
+ }
+
+ *psPredictionEncoder_out = psPredictionEncoder;
+
+ return IVAS_ERR_OK;
+}
+ivas_error CreatePredictionEncoder(
+ PredictionEncoder **psPredictionEncoder_out,
+ const int32_t iChannels,
+ const int32_t iNumBlocks,
+ const int32_t iNumSubSets,
+ const int32_t iMaxNumPredBands )
+{
+ int32_t k, n;
+ PredictionEncoder *psPredictionEncoder = NULL;
+
+ if ( ( psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ psPredictionEncoder->iChannels = iChannels;
+ psPredictionEncoder->iNumBlocks = iNumBlocks;
+ psPredictionEncoder->iSubSetId = 0;
+ psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands;
+ psPredictionEncoder->iNumSubSets = iNumSubSets;
+
+ if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ if ( ( psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ for ( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ psPredictionEncoder->piPredChanEnable[n] = 0;
+ psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly
+ }
+
+ if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->pppfInpBufReal = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->pppfInpBufImag = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfInpPrevReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfInpPrevImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateRealTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateImagTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ for ( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->pppfInpBufReal[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->pppfInpBufImag[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ )
+ {
+ if ( ( psPredictionEncoder->pppfInpBufReal[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->pppfInpBufImag[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set_zero( psPredictionEncoder->pppfInpBufReal[n][k], LCLD_BANDS );
+ set_zero( psPredictionEncoder->pppfInpBufImag[n][k], LCLD_BANDS );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set_zero( psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS );
+ set_zero( psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS );
+
+ if ( ( psPredictionEncoder->ppfInpPrevReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfInpPrevImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+
+ set_zero( psPredictionEncoder->ppfInpPrevReal[n], LCLD_BANDS );
+ set_zero( psPredictionEncoder->ppfInpPrevImag[n], LCLD_BANDS );
+
+ if ( ( psPredictionEncoder->ppfPredStateRealTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ if ( ( psPredictionEncoder->ppfPredStateImagTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) );
+ }
+ set_zero( psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS );
+ set_zero( psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS );
+ for ( k = 0; k < LCLD_BANDS; k++ )
+ {
+ psPredictionEncoder->ppiPredBandEnable[n][k] = 0;
+ psPredictionEncoder->ppfA1Real[n][k] = 0.0f;
+ psPredictionEncoder->ppfA1Imag[n][k] = 0.0f;
+ }
+ }
+
+ *psPredictionEncoder_out = psPredictionEncoder;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function DeletePredictionEncoder()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void DeletePredictionEncoder_fx(
+ PredictionEncoder *psPredictionEncoder )
+{
+ Word32 n;
+ FOR( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ Word32 k;
+ free( psPredictionEncoder->ppiPredBandEnable[n] );
+ free( psPredictionEncoder->ppfA1Real_fx[n] );
+ free( psPredictionEncoder->ppfA1Imag_fx[n] );
+ free( psPredictionEncoder->ppiA1Mag[n] );
+ free( psPredictionEncoder->ppiA1Phase[n] );
+ FOR( k = 0; k < LCLD_PRED_WIN_LEN; k++ )
+ {
+ free( psPredictionEncoder->pppfInpBufReal_fx[n][k] );
+ free( psPredictionEncoder->pppfInpBufImag_fx[n][k] );
+ }
+ free( psPredictionEncoder->pppfInpBufReal_fx[n] );
+ free( psPredictionEncoder->pppfInpBufImag_fx[n] );
+ free( psPredictionEncoder->ppfInpPrevReal_fx[n] );
+ free( psPredictionEncoder->ppfInpPrevImag_fx[n] );
+ free( psPredictionEncoder->ppfPredStateReal_fx[n] );
+ free( psPredictionEncoder->ppfPredStateImag_fx[n] );
+ free( psPredictionEncoder->ppfPredStateRealTmp_fx[n] );
+ free( psPredictionEncoder->ppfPredStateImagTmp_fx[n] );
+ }
+ free( psPredictionEncoder->piPredChanEnable );
+ free( psPredictionEncoder->piNumPredBands );
+ free( psPredictionEncoder->ppiPredBandEnable );
+ free( psPredictionEncoder->ppfA1Real_fx );
+ free( psPredictionEncoder->ppfA1Imag_fx );
+ free( psPredictionEncoder->ppiA1Mag );
+ free( psPredictionEncoder->ppiA1Phase );
+ free( psPredictionEncoder->pppfInpBufReal_fx );
+ free( psPredictionEncoder->pppfInpBufImag_fx );
+ free( psPredictionEncoder->ppfInpPrevReal_fx );
+ free( psPredictionEncoder->ppfInpPrevImag_fx );
+ free( psPredictionEncoder->ppfPredStateReal_fx );
+ free( psPredictionEncoder->ppfPredStateImag_fx );
+ free( psPredictionEncoder->ppfPredStateRealTmp_fx );
+ free( psPredictionEncoder->ppfPredStateImagTmp_fx );
+
+
+ free( psPredictionEncoder );
+
+ return;
+}
+void DeletePredictionEncoder(
+ PredictionEncoder *psPredictionEncoder )
+{
+ int32_t n;
+ for ( n = 0; n < psPredictionEncoder->iChannels; n++ )
+ {
+ int32_t k;
+ free( psPredictionEncoder->ppiPredBandEnable[n] );
+ free( psPredictionEncoder->ppfA1Real[n] );
+ free( psPredictionEncoder->ppfA1Imag[n] );
+ free( psPredictionEncoder->ppiA1Mag[n] );
+ free( psPredictionEncoder->ppiA1Phase[n] );
+ for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ )
+ {
+ free( psPredictionEncoder->pppfInpBufReal[n][k] );
+ free( psPredictionEncoder->pppfInpBufImag[n][k] );
+ }
+ free( psPredictionEncoder->pppfInpBufReal[n] );
+ free( psPredictionEncoder->pppfInpBufImag[n] );
+ free( psPredictionEncoder->ppfInpPrevReal[n] );
+ free( psPredictionEncoder->ppfInpPrevImag[n] );
+ free( psPredictionEncoder->ppfPredStateReal[n] );
+ free( psPredictionEncoder->ppfPredStateImag[n] );
+ free( psPredictionEncoder->ppfPredStateRealTmp[n] );
+ free( psPredictionEncoder->ppfPredStateImagTmp[n] );
+ }
+ free( psPredictionEncoder->piPredChanEnable );
+ free( psPredictionEncoder->piNumPredBands );
+ free( psPredictionEncoder->ppiPredBandEnable );
+ free( psPredictionEncoder->ppfA1Real );
+ free( psPredictionEncoder->ppfA1Imag );
+ free( psPredictionEncoder->ppiA1Mag );
+ free( psPredictionEncoder->ppiA1Phase );
+ free( psPredictionEncoder->pppfInpBufReal );
+ free( psPredictionEncoder->pppfInpBufImag );
+ free( psPredictionEncoder->ppfInpPrevReal );
+ free( psPredictionEncoder->ppfInpPrevImag );
+ free( psPredictionEncoder->ppfPredStateReal );
+ free( psPredictionEncoder->ppfPredStateImag );
+ free( psPredictionEncoder->ppfPredStateRealTmp );
+ free( psPredictionEncoder->ppfPredStateImagTmp );
+
+
+ free( psPredictionEncoder );
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function ComputePredictors()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ComputePredictors(
+ PredictionEncoder *psPredictionEncoder,
+ float ***pppfReal,
+ float ***pppfImag )
+{
+ int32_t c;
+
+ int32_t b0 = psPredictionEncoder->iSubSetId;
+ int32_t bstep = psPredictionEncoder->iNumSubSets;
+ int32_t iNumBlocks = psPredictionEncoder->iNumBlocks;
+ float ***pppfRealBuf;
+ float ***pppfImagBuf;
+ float pfEstPredBitGain[LCLD_BANDS] = { 0 };
+
+ if ( iNumBlocks < LCLD_PRED_WIN_LEN )
+ {
+ pppfRealBuf = psPredictionEncoder->pppfInpBufReal;
+ pppfImagBuf = psPredictionEncoder->pppfInpBufImag;
+ for ( c = 0; c < psPredictionEncoder->iChannels; c++ )
+ {
+ int32_t n;
+ for ( n = 0; n < LCLD_PRED_WIN_LEN - iNumBlocks; n++ )
+ {
+ mvr2r( pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS );
+ mvr2r( pppfImagBuf[c][n + iNumBlocks], pppfImagBuf[c][n], LCLD_BANDS );
+ }
+ for ( n = 0; n < iNumBlocks; n++ )
+ {
+ mvr2r( pppfReal[c][n], pppfRealBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS );
+ mvr2r( pppfImag[c][n], pppfImagBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS );
+ }
+ }
+ }
+ else
+ {
+ pppfRealBuf = pppfReal;
+ pppfImagBuf = pppfImag;
+ }
+
+ for ( c = 0; c < psPredictionEncoder->iChannels; c++ )
+ {
+ int32_t b;
+ for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
+ {
+ int32_t n;
+ float fGain = 0.0;
+ float fBitGain = 0.0;
+ float *pfRxxReal;
+ float *pfRxxImag;
+ float fA1Real;
+ float fA1Imag;
+ int32_t iA1Mag;
+ int32_t iA1Phase;
+
+ pfRxxReal = psPredictionEncoder->pfRxxReal;
+ pfRxxImag = psPredictionEncoder->pfRxxImag;
+
+ pfRxxReal[0] = 0.0;
+ pfRxxImag[0] = 0.0;
+ for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ )
+ {
+ pfRxxReal[0] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b] );
+ }
+
+ pfRxxReal[1] = 0.0;
+ pfRxxImag[1] = 0.0;
+ for ( n = 1; n < LCLD_PRED_WIN_LEN; n++ )
+ {
+ pfRxxReal[1] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b] );
+ pfRxxImag[1] += ( pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b] );
+ }
+
+ if ( pfRxxReal[0] > 1e-12f )
+ {
+ float fA1Mag;
+ float fA1Phase;
+ float fGain2;
+ float fBitGain2;
+ int32_t iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN );
+
+ const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI;
+ const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f );
+ const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI;
+ const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) );
+
+ /* Compute filter coefficeints */
+ fA1Real = -pfRxxReal[1] / pfRxxReal[0];
+ fA1Imag = -pfRxxImag[1] / pfRxxReal[0];
+
+ /* compute these before quant */
+ /* Compute est coding gain based on quantized filter coefficients */
+ fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag );
+ fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1)
+ fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag );
+ fA1Mag = fMagScale * asinf( fA1Mag );
+ iA1Mag = (int32_t) ( fA1Mag + 0.5f );
+ iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN;
+ iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX;
+ fA1Mag = sinf( fInvMagScale * (float) iA1Mag );
+
+ fA1Phase = atan2f( fA1Imag, fA1Real );
+ fA1Phase = fPhaseScale * fA1Phase;
+ iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f );
+ iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN;
+ iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap?
+ fA1Phase = fInvPhaseScale * (float) iA1Phase;
+
+ fA1Real = fA1Mag * cosf( fA1Phase );
+ fA1Imag = fA1Mag * sinf( fA1Phase );
+
+ fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag );
+ fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1)
+ fGain = ( fGain < fGain2 ) ? fGain : fGain2;
+ fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2;
+ }
+ else
+ {
+ fA1Real = 0.0f;
+ fA1Imag = 0.0f;
+ iA1Mag = 0;
+ iA1Phase = 0;
+ fGain = -10.0f; // Fix this
+ }
+
+ pfEstPredBitGain[b] = fBitGain;
+ psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable
+ psPredictionEncoder->ppfA1Real[c][b] = fA1Real;
+ psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag;
+ psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag;
+ psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase;
+ }
+
+ {
+ float fBestCost;
+ int32_t iPredBands;
+ float fBitGain;
+ int32_t iPredChanEnable = 0;
+
+ fBestCost = 0.0;
+ iPredBands = 0;
+ fBitGain = -7.0;
+ for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
+ { // still getting this decision wrong!
+ fBitGain -= 1.0;
+ if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 )
+ {
+ fBitGain += pfEstPredBitGain[b];
+ }
+ if ( fBitGain > fBestCost )
+ {
+ fBestCost = fBitGain;
+ iPredBands = b;
+ iPredChanEnable = 1;
+ }
+ }
+
+ if ( iPredChanEnable == 1 )
+ {
+ for ( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep )
+ {
+ psPredictionEncoder->ppiPredBandEnable[c][b] = 0;
+ }
+ activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
+ psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep;
+ }
+ else
+ {
+ for ( b = b0; b < LCLD_BANDS; b += bstep )
+ {
+ psPredictionEncoder->ppiPredBandEnable[c][b] = 0;
+ }
+ deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
+ psPredictionEncoder->piNumPredBands[c] = 0;
+ }
+ }
+ }
+}
+
+void ComputePredictors_fx(
+ PredictionEncoder *psPredictionEncoder,
+ Word32 ***pppfReal_fx, // Q12?
+ Word32 ***pppfImag_fx ) // Q12?
+{
+ Word32 c;
+
+ Word32 b0 = psPredictionEncoder->iSubSetId;
+ Word32 bstep = psPredictionEncoder->iNumSubSets;
+ Word32 iNumBlocks = psPredictionEncoder->iNumBlocks;
+ /*float ***pppfRealBuf;
+ float ***pppfImagBuf;*/
+ Word32 ***pppfRealBuf_fx;
+ Word32 ***pppfImagBuf_fx;
+ // float pfEstPredBitGain[LCLD_BANDS] = { 0 };
+ Word32 pfEstPredBitGain_fx[LCLD_BANDS] = { 0 };
+
+ IF( LT_32( iNumBlocks, LCLD_PRED_WIN_LEN ) )
+ {
+ /*pppfRealBuf = psPredictionEncoder->pppfInpBufReal;
+ pppfImagBuf = psPredictionEncoder->pppfInpBufImag;*/
+ pppfRealBuf_fx = psPredictionEncoder->pppfInpBufReal_fx;
+ move32();
+ pppfImagBuf_fx = psPredictionEncoder->pppfInpBufImag_fx;
+ move32();
+ FOR( c = 0; c < psPredictionEncoder->iChannels; c++ )
+ {
+ Word32 n;
+ FOR( n = 0; n < L_sub( LCLD_PRED_WIN_LEN, iNumBlocks ); n++ )
+ {
+ /*mvr2r(pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS);
+ mvr2r(pppfImagBuf[c][n + iNumBlocks], pppfImagBuf[c][n], LCLD_BANDS);*/
+ mvl2l( pppfRealBuf_fx[c][n + iNumBlocks], pppfRealBuf_fx[c][n], LCLD_BANDS );
+ mvl2l( pppfImagBuf_fx[c][n + iNumBlocks], pppfImagBuf_fx[c][n], LCLD_BANDS );
+ }
+ FOR( n = 0; n < iNumBlocks; n++ )
+ {
+ /*mvr2r(pppfReal[c][n], pppfRealBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS);
+ mvr2r(pppfImag[c][n], pppfImagBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS);*/
+ mvl2l( pppfReal_fx[c][n], pppfRealBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS );
+ mvl2l( pppfImag_fx[c][n], pppfImagBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS );
+ }
+ }
+ }
+ ELSE
+ {
+ /*pppfRealBuf = pppfReal;
+ pppfImagBuf = pppfImag;*/
+ pppfRealBuf_fx = pppfReal_fx;
+ move32();
+ pppfImagBuf_fx = pppfImag_fx;
+ move32();
+ }
+
+ FOR( c = 0; c < psPredictionEncoder->iChannels; c++ )
+ {
+ Word32 b;
+ FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
+ {
+ Word32 n;
+ /*float fGain = 0.0;
+ float fBitGain = 0.0;
+ float *pfRxxReal;
+ float *pfRxxImag;
+ float fA1Real;
+ float fA1Imag;*/
+ Word32 fGain_fx = 0;
+ Word32 fBitGain_fx = 0;
+ Word32 *pfRxxReal_fx;
+ Word32 *pfRxxImag_fx;
+ Word32 fA1Real_fx;
+ Word32 fA1Imag_fx;
+ Word32 L_temp;
+ Word64 W_temp1, W_temp2;
+ Word32 iA1Mag;
+ Word32 iA1Phase;
+
+ /*pfRxxReal = psPredictionEncoder->pfRxxReal;
+ pfRxxImag = psPredictionEncoder->pfRxxImag;*/
+ pfRxxReal_fx = psPredictionEncoder->pfRxxReal_fx;
+ move32();
+ pfRxxImag_fx = psPredictionEncoder->pfRxxImag_fx;
+ move32();
+ /*pfRxxReal[0] = 0.0;
+ pfRxxImag[0] = 0.0;*/
+ pfRxxReal_fx[0] = 0;
+ move32();
+ pfRxxImag_fx[0] = 0;
+ move32();
+ W_temp1 = 0;
+ FOR( n = 0; n < LCLD_PRED_WIN_LEN; n++ )
+ {
+ // pfRxxReal[0] += (pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b]);
+ W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n][b] ),
+ W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n][b] ) ) ); // Q40
+ }
+ Word16 w_norm1 = W_norm( W_temp1 );
+ W_temp1 = W_shr( W_temp1, 32 - w_norm1 );
+ pfRxxReal_fx[0] = W_extract_l( W_temp1 );
+ /*pfRxxReal[1] = 0.0;
+ pfRxxImag[1] = 0.0;*/
+ pfRxxReal_fx[1] = 0;
+ move32();
+ pfRxxImag_fx[1] = 0;
+ move32();
+ W_temp1 = 0;
+ W_temp2 = 0;
+ FOR( n = 1; n < LCLD_PRED_WIN_LEN; n++ )
+ {
+ /*pfRxxReal[1] += (pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b]);
+ pfRxxImag[1] += (pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b]);*/
+ W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ),
+ W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40
+ W_temp2 = W_add( W_temp2, W_sub( W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ),
+ W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40
+ }
+
+ Word16 w_norm2 = W_norm( W_temp1 );
+ W_temp1 = W_shr( W_temp1, 32 - w_norm2 );
+ pfRxxReal_fx[1] = W_extract_l( W_temp1 );
+ Word16 w_norm3 = W_norm( W_temp2 );
+ W_temp2 = W_shr( W_temp2, 32 - w_norm3 );
+ pfRxxImag_fx[1] = W_extract_l( W_temp2 );
+ Word16 final_w_norm = min( w_norm1, min( w_norm2, w_norm3 ) );
+ pfRxxReal_fx[0] = L_shr( pfRxxReal_fx[0], w_norm1 - final_w_norm ); // Q8 + final_w_norm
+ pfRxxReal_fx[1] = L_shr( pfRxxReal_fx[1], w_norm2 - final_w_norm ); // Q8 + final_w_norm
+ pfRxxImag_fx[1] = L_shr( pfRxxImag_fx[1], w_norm3 - final_w_norm ); // Q8 + final_w_norm
+ // if (pfRxxReal[0] > 1e-12f)
+ IF( GT_32( pfRxxReal_fx[0], 0 ) )
+ {
+ /*float fA1Mag;
+ float fA1Phase;
+ float fGain2;
+ float fBitGain2;*/
+ Word32 fA1Mag_fx;
+ Word32 fA1Phase_fx;
+ Word32 fGain2_fx;
+ Word32 fBitGain2_fx;
+ Word32 iNumBlocksPerPredCoef = L_min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN );
+ const Word32 fMagScale_fx32 = 1452576210; // Q28
+ move32();
+ // const float fInvMagScale = M_PI / (2.0f * (float)(1 << (PRED_QUNAT_FILTER_MAG_BITS)) + 1.0f);
+ const Word16 fInvMagScale_fx = 6055; // Q15
+ move16();
+ // const float fPhaseScale = (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1)) / M_PI
+ const Word32 fPhaseScale_fx32 = 1367130551; // Q28
+ // const float fInvPhaseScale = M_PI / (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1));
+ const Word16 fInvPhaseScale_fx = 6434; // Q15
+ move16();
+
+ /* Compute filter coefficeints */
+ // fA1Real = -pfRxxReal[1] / pfRxxReal[0];
+ Word16 sf_r, sf_i;
+ fA1Real_fx = BASOP_Util_Divide3232_Scale( -pfRxxReal_fx[1], pfRxxReal_fx[0], &sf_r );
+ // fA1Imag = -pfRxxImag[1] / pfRxxReal[0];
+ fA1Imag_fx = BASOP_Util_Divide3232_Scale( -pfRxxImag_fx[1], pfRxxReal_fx[0], &sf_i );
+
+ IF( GT_16( sf_r, sf_i ) )
+ {
+ fA1Imag_fx = L_shr( fA1Imag_fx, sub( sf_r, sf_i ) );
+ sf_i = sf_r;
+ move16();
+ }
+ ELSE IF( LT_16( sf_r, sf_i ) )
+ {
+ fA1Real_fx = L_shr( fA1Real_fx, sub( sf_i, sf_r ) );
+ sf_r = sf_i;
+ move16();
+ }
+ Word32 L_temp_1;
+ IF( LT_16( sf_r, -7 ) )
+ {
+ fA1Real_fx = L_shr( fA1Real_fx, sub( -8, sf_r ) );
+ fA1Imag_fx = L_shr( fA1Imag_fx, sub( -8, sf_i ) );
+ sf_r = sf_i = -8;
+ move16();
+ L_temp_1 = MAX_32;
+ move32();
+ }
+ ELSE
+ {
+ L_temp_1 = L_shl( 1, sub( 15, shl( sf_r, 1 ) ) );
+ }
+ /* compute these before quant */
+ /* Compute est coding gain based on quantized filter coefficients */
+ // fGain = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag);
+ L_temp = L_sub( L_sub( L_temp_1, mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) );
+ Word16 exp = norm_l( L_temp );
+ IF( LT_16( exp, 16 ) )
+ {
+ L_temp = L_shr( L_temp, sub( 16, exp ) );
+ exp = add( sub( 16, exp ), shl( sf_r, 1 ) );
+ }
+ else
+ {
+ exp = shl( sf_r, 1 );
+ }
+ // fGain_fx = sub(sub(32767, extract_h(Mpy_32_32(fA1Real_fx, fA1Real_fx))), extract_h(Mpy_32_32(fA1Imag_fx, fA1Imag_fx)));
+ // fGain_fx = extract_l(L_shl(L_temp, 2*sf_r));
+ fGain_fx = extract_l( L_temp );
+ fGain_fx = max( 1, fGain_fx );
+ fGain_fx = Inv16( extract_l( fGain_fx ), &exp ); // Q15 - exp
+ // fGain_fx = L_shl(fGain_fx, exp); //Q15
+ // fBitGain = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1)
+ // fBitGain_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15
+ W_temp1 = W_mult0_32_32( L_shr( Mpy_32_32( 1395864371, L_add( BASOP_Util_Log2( fGain_fx ), L_shl( add( 16, exp ), 25 ) ) ), 10 ), iNumBlocksPerPredCoef );
+ Word16 w_norm4 = W_norm( W_temp1 );
+ IF( LT_16( w_norm4, 32 ) )
+ {
+ W_temp1 = W_shr( W_temp1, 32 - w_norm4 );
+ w_norm4 = sub( 32, w_norm4 );
+ }
+ ELSE
+ {
+ w_norm4 = 0;
+ move16();
+ }
+ fBitGain_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15
+ // fA1Mag = sqrtf(fA1Real * fA1Real + fA1Imag * fA1Imag);
+ fA1Mag_fx = L_add( mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) ); // Q15 - 2*sf_r
+ // fA1Mag = fMagScale * asinf(fA1Mag);
+ exp = 0;
+ move16();
+ L_temp = L_sub( L_temp_1, fA1Mag_fx ); // Q15 - 2*sf_r
+ IF( NE_32( L_temp, 0 ) )
+ {
+ fA1Mag_fx = BASOP_Util_Divide3232_Scale( fA1Mag_fx, L_temp, &exp );
+ }
+ ELSE
+ {
+ fA1Mag_fx = 0;
+ move32();
+ exp = 0;
+ move16();
+ }
+ fA1Mag_fx = L_shl( fA1Mag_fx, 16 );
+ IF( fA1Mag_fx > 0 )
+ {
+ fA1Mag_fx = Sqrt32( fA1Mag_fx, &exp );
+ }
+ ELSE
+ {
+ fA1Mag_fx = 0;
+ move32();
+ exp = 0;
+ move16();
+ }
+
+ fA1Mag_fx = BASOP_util_atan( L_shr_r_sat( fA1Mag_fx, 6 - exp ) ); // Q14
+ fA1Mag_fx = Mpy_32_16_1( fMagScale_fx32, extract_l( fA1Mag_fx ) ); // Q27
+
+ // iA1Mag = (int32_t)(fA1Mag + 0.5f);
+ IF( GE_32( fA1Mag_fx, 0 ) )
+ {
+ iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0
+ }
+ ELSE
+ {
+ fA1Mag_fx = L_negate( fA1Mag_fx );
+ iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0
+ iA1Mag = L_negate( iA1Mag );
+ }
+ iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN;
+ iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX;
+ // fA1Mag = sinf(fInvMagScale * (float)iA1Mag);
+ fA1Mag_fx = L_deposit_l( getSinWord16( extract_l( L_shr( L_mult0( extract_l( fInvMagScale_fx ), extract_l( iA1Mag ) ), 2 ) ) ) ); // Q14
+
+ // fA1Phase = atan2f(fA1Imag, fA1Real);
+ fA1Phase_fx = BASOP_util_atan2( fA1Imag_fx, fA1Real_fx, 0 ); // Q13
+ // fA1Phase = fPhaseScale * fA1Phase;
+ fA1Phase_fx = Mpy_32_16_1( fPhaseScale_fx32, extract_l( fA1Phase_fx ) ); // Q26
+ // iA1Phase = (fA1Phase > 0.0f) ? (int32_t)(fA1Phase + 0.5f) : (int32_t)(fA1Phase - 0.5f);
+ // iA1Phase = (fA1Phase_fx > 0) ? shr(add(fA1Phase_fx, 512), 10) : shr(sub(fA1Phase_fx, 512), 10);
+ IF( GE_32( fA1Phase_fx, 0 ) )
+ {
+ iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0
+ }
+ ELSE
+ {
+ fA1Phase_fx = L_negate( fA1Phase_fx );
+ iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0
+ iA1Phase = L_negate( iA1Phase );
+ }
+ iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN;
+ iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap?
+ // fA1Phase = fInvPhaseScale * (float)iA1Phase;
+ L_temp = L_mult0( fInvPhaseScale_fx, (Word16) iA1Phase ); // Q15
+
+ // fA1Real = fA1Mag * cosf(fA1Phase);
+ fA1Real_fx = L_mult0( extract_l( fA1Mag_fx ), getCosWord16( extract_l( L_shr( L_temp, 2 ) ) ) ); // Q28
+ // fA1Imag = fA1Mag * sinf(fA1Phase);
+ fA1Imag_fx = L_mult0( extract_l( fA1Mag_fx ), getSinWord16( extract_l( L_shr( L_temp, 2 ) ) ) ); // Q28
+
+ // fGain2 = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag);
+ exp = 0;
+ fGain2_fx = sub( sub( 32767, mult_r( extract_l( L_shr( fA1Real_fx, 13 ) ), extract_l( L_shr( fA1Real_fx, 13 ) ) ) ), mult_r( extract_l( L_shr( fA1Imag_fx, 13 ) ), extract_l( L_shr( fA1Imag_fx, 13 ) ) ) );
+ fGain2_fx = L_max( 1, fGain2_fx );
+ fGain2_fx = Inv16( extract_l( fGain2_fx ), &exp ); // Q15-exp
+ fGain2_fx = L_shl( fGain2_fx, exp );
+ // fBitGain2 = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1)
+ // fBitGain2_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15
+ fBitGain2_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15
+ // fGain = (fGain < fGain2) ? fGain : fGain2;
+ fGain_fx = ( fGain_fx < fGain2_fx ) ? fGain_fx : fGain2_fx;
+ // fBitGain = (fBitGain < fBitGain2) ? fBitGain : fBitGain2;
+ fBitGain_fx = ( fBitGain_fx < fBitGain2_fx ) ? fBitGain_fx : fBitGain2_fx;
+ }
+ ELSE
+ {
+ /*fA1Real = 0.0f;
+ fA1Imag = 0.0f;*/
+ fA1Real_fx = 0;
+ move32();
+ fA1Imag_fx = 0;
+ move32();
+ iA1Mag = 0;
+ move32();
+ iA1Phase = 0;
+ move32();
+ // fGain = -10.0f; // Fix this
+ fGain_fx = -327680; // Fix this
+ move32();
+ }
+
+ // pfEstPredBitGain[b] = fBitGain;
+ // psPredictionEncoder->ppiPredBandEnable[c][b] = (fBitGain > 0.0f); // Initial prediction enable
+ // psPredictionEncoder->ppfA1Real[c][b] = fA1Real;
+ // psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag;
+ pfEstPredBitGain_fx[b] = fBitGain_fx; // Q15
+ move32();
+ // printf("\n %d %d %f %f %f ", iA1Mag, iA1Phase, (float)fBitGain_fx / 32768, (float)fA1Real_fx / ONE_IN_Q28, (float)fA1Imag_fx / ONE_IN_Q28);
+ psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain_fx > 0 ); // Initial prediction enable
+ psPredictionEncoder->ppfA1Real_fx[c][b] = L_shl( fA1Real_fx, Q3 ); // Q31
+ psPredictionEncoder->ppfA1Imag_fx[c][b] = L_shl( fA1Imag_fx, Q3 ); // Q31
+ psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag;
+ move32();
+ psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase;
+ move32();
+ }
+
+ {
+ // float fBestCost;
+ Word32 fBestCost_fx;
+ Word32 iPredBands;
+ // float fBitGain;
+ Word32 fBitGain_fx;
+ Word32 iPredChanEnable = 0;
+
+ // fBestCost = 0.0;
+ fBestCost_fx = 0;
+ move32();
+ iPredBands = 0;
+ move32();
+ // fBitGain = -7.0;
+ fBitGain_fx = -229376; // Q15
+ move32();
+ FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep )
+ { // still getting this decision wrong!
+ // fBitGain -= 1.0;
+ fBitGain_fx = L_sub( fBitGain_fx, 32768 );
+ IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) )
+ {
+ // fBitGain += pfEstPredBitGain[b];
+ fBitGain_fx = L_add( fBitGain_fx, pfEstPredBitGain_fx[b] );
+ }
+ // if (fBitGain > fBestCost)
+ IF( GT_32( fBitGain_fx, fBestCost_fx ) )
+ {
+ fBestCost_fx = fBitGain_fx;
+ iPredBands = b;
+ iPredChanEnable = 1;
+ }
+ }
+
+ IF( EQ_32( iPredChanEnable, 1 ) )
+ {
+ FOR( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep )
+ {
+ psPredictionEncoder->ppiPredBandEnable[c][b] = 0;
+ }
+ activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
+ psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep;
+ }
+ ELSE
+ {
+ FOR( b = b0; b < LCLD_BANDS; b += bstep )
+ {
+ psPredictionEncoder->ppiPredBandEnable[c][b] = 0;
+ }
+ deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId );
+ psPredictionEncoder->piNumPredBands[c] = 0;
+ move32();
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------*
+ * Function ApplyForwardPredictors()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Function WritePredictors()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 WritePredictors(
+ PredictionEncoder *psPredictionEncoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsWritten = 0;
+ Word32 c;
+ Word32 iNumSubSets = psPredictionEncoder->iNumSubSets;
+ Word32 iSubSetId = psPredictionEncoder->iSubSetId;
+ Word32 iNumPredBandBits = 6;
+ const Word16 iSubSetBits = ( GT_16( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 );
+ move32();
+ move32();
+ move16();
+
+ /* number of subsets */
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iNumSubSets, 1 ), iSubSetBits ); /* otherwise use default */
+ iBitsWritten = L_add( iBitsWritten, iSubSetBits );
+
+ IF( GT_32( iNumSubSets, 1 ) )
+ {
+ /* write current subset */
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits );
+ iBitsWritten = L_add( iBitsWritten, iSubSetBits );
+ iNumPredBandBits = ( GE_32( iNumSubSets, 4 ) ? 4 : 5 );
+ move32();
+ }
+
+ FOR( c = 0; c < psPredictionEncoder->iChannels; c++ )
+ {
+ Word32 b;
+ Word32 b0 = iSubSetId;
+ move32();
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets );
+ iBitsWritten = L_add( iBitsWritten, iNumSubSets );
+
+ IF( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) )
+ {
+ Word32 iNumPredBands = L_sub( psPredictionEncoder->piNumPredBands[c], b0 ) / iNumSubSets;
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits );
+ iBitsWritten = L_add( iBitsWritten, iNumPredBandBits );
+
+ FOR( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+
+ IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) )
+ {
+ Word32 iA1Mag;
+ Word32 iA1Phase;
+
+ iA1Mag = psPredictionEncoder->ppiA1Mag[c][b];
+ move32();
+ iA1Phase = L_sub( psPredictionEncoder->ppiA1Phase[c][b], PRED_QUANT_FILTER_PHASE_MIN );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS );
+ iBitsWritten = L_add( iBitsWritten, PRED_QUNAT_FILTER_MAG_BITS );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS );
+ iBitsWritten = L_add( iBitsWritten, PRED_QUANT_FILTER_PHASE_BITS );
+ }
+ }
+ }
+ }
+
+ return iBitsWritten;
+}
+#endif
diff --git a/lib_isar/isar_RMSEnvGrouping.c b/lib_isar/isar_RMSEnvGrouping.c
new file mode 100644
index 0000000000000000000000000000000000000000..0c24040be1d7f1fbb15feb8a4927bba13c08488a
--- /dev/null
+++ b/lib_isar/isar_RMSEnvGrouping.c
@@ -0,0 +1,964 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+/* Double check cost function calculation */
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "prot.h"
+#include "isar_lcld_prot.h"
+#include "isar_lcld_rom_tables.h"
+#include "wmc_auto.h"
+#include "prot_fx2.h"
+#include "basop_util.h"
+#include "enh64.h"
+Word32 Inv_grp_length[17] = {
+ // Q31
+ 0,
+ 2147483647,
+ 1073741823,
+ 715827882,
+ 536870911,
+ 429496729,
+ 357913941,
+ 306783378,
+ 268435455,
+ 238609294,
+ 214748364,
+ 195225786,
+ 178956970,
+ 165191049,
+ 153391689,
+ 143165576,
+ 134217727,
+
+};
+
+/*-------------------------------------------------------------------*
+ * Local ROM tables
+ *
+ *
+ *-------------------------------------------------------------------*/
+static const Word32 c_afThreshQuiet48_fx[23] = {
+ // Q23
+ -705191424,
+ -705191424,
+ -705191424,
+ -705191424,
+ -705191424,
+ -705191424,
+ -705191424,
+ -705191424,
+ -703021824,
+ -694920256,
+ -685375488,
+ -662531840,
+ -646432768,
+ -636262784,
+ -627448000,
+ -618652544,
+ -598245120,
+ -575579520,
+ -550540736,
+ -508787360,
+ -264583456,
+ -161516096,
+ -158042848,
+};
+static const Word32 c_fiDefaultTheta48_fx[MAX_BANDS_48] = {
+ // Q31
+ 939524096,
+ 939524096,
+ 805306368,
+ 671088640,
+ 671088640,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+ 536870912,
+};
+typedef struct GMNODE
+{
+ int32_t iGroupStart;
+ int32_t iGroupLength;
+ Word32 *pfMergedEnergydB_fx;
+ int32_t *piQRMSEnvelope;
+
+ int32_t iGroupRMSEnvelopeCost;
+ Word32 fGroupSNRPenalty_fx;
+ Word16 fGroupSNRPenalty_exp;
+ struct GMNODE *psNext;
+} GMNode;
+
+struct RMS_ENVELOPE_GROUPING
+{
+ int32_t iNumBlocks;
+ int32_t iMaxGroups;
+ Word32 **ppfWeight_man;
+ Word16 **ppfWeight_exp;
+ Word32 **ppfBandEnergy_man;
+ Word16 **ppfBandEnergy_exp;
+ Word32 **ppfBandEnergydB_fx;
+ // Word32 **ppfWeight_fx;
+ GMNode *psGMNodes;
+};
+
+
+/*-------------------------------------------------------------------*
+ * Function CreateRMSEnvelopeGrouping()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping(
+ const Word32 iNumBlocks )
+{
+ Word32 n;
+
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping;
+
+ psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) );
+ psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks;
+
+ psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1;
+ psRMSEnvelopeGrouping->ppfBandEnergy_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) );
+ psRMSEnvelopeGrouping->ppfBandEnergy_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) );
+ psRMSEnvelopeGrouping->ppfBandEnergydB_fx = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) );
+ psRMSEnvelopeGrouping->ppfWeight_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) );
+ psRMSEnvelopeGrouping->ppfWeight_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) );
+
+ for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
+ {
+ psRMSEnvelopeGrouping->ppfBandEnergy_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); /* 2 for stereo joint group calc */
+ psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) ); /* 2 for stereo joint group calc */
+ psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) );
+ psRMSEnvelopeGrouping->ppfWeight_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) );
+ psRMSEnvelopeGrouping->ppfWeight_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) );
+ }
+
+ psRMSEnvelopeGrouping->psGMNodes = (GMNode *) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( GMNode ) );
+ for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
+ {
+ psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( float ) );
+ psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) );
+ psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1;
+ psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 );
+ psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1;
+ }
+
+ return psRMSEnvelopeGrouping;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function DeleteRMSEnvelopeGrouping()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void DeleteRMSEnvelopeGrouping(
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping )
+{
+ int32_t n;
+
+ for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
+ {
+ free( psRMSEnvelopeGrouping->ppfBandEnergy_man[n] );
+ free( psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] );
+ free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] );
+ free( psRMSEnvelopeGrouping->ppfWeight_man[n] );
+ free( psRMSEnvelopeGrouping->ppfWeight_exp[n] );
+ }
+ free( psRMSEnvelopeGrouping->ppfBandEnergy_man );
+ free( psRMSEnvelopeGrouping->ppfBandEnergy_exp );
+ free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx );
+ free( psRMSEnvelopeGrouping->ppfWeight_man );
+ free( psRMSEnvelopeGrouping->ppfWeight_exp );
+
+
+ for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ )
+ {
+ free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx );
+ free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope );
+ }
+ free( psRMSEnvelopeGrouping->psGMNodes );
+
+ free( psRMSEnvelopeGrouping );
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function ComputeBandEnergy()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void ComputeBandEnergy(
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx,
+ Word32 **ppfBandEnergy_man,
+ Word16 **ppfBandEnergy_exp,
+ Word32 **ppfBandEnergydB_fx,
+ Word32 **ppfWeight_man,
+ Word16 **ppfWeight_exp,
+ Word16 q_final )
+{
+
+ Word32 n;
+ Word32 constant = 1616142483; // Q29 of(1/log2(10))*10
+ Word32 const_comp3, const_comp1;
+ Word16 exp3 = 0, exp1 = 0, Flag1, Flag2, Flag3;
+ Word16 div_exp;
+ /*For 0.33f*/
+ const_comp3 = 1417339264;
+ move32();
+ exp3 = -1;
+ move16();
+ // f2me( 0.33, &const_comp3, &exp3 );//
+ // f2me( 1.0, &const_comp1, &exp1 );//
+ /*For 1.0f*/
+ Word32 mul_32;
+ Word16 mul_exp;
+ const_comp1 = 1073741824;
+ move32();
+ exp1 = 1;
+ move16();
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 k;
+ Word32 iChanOffset;
+
+ iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) );
+ FOR( k = 0; k < iNumBlocks; k++ )
+ {
+ Word32 b;
+ Word32 iFBOffset;
+ Word32 fMaxWeight_fx = 0;
+ move32();
+ Word16 fMaxWeight_exp = 0;
+ move16();
+ iFBOffset = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 m;
+ Word16 fEnergy_exp;
+ Word32 fEnergy_fx, fWeight_temp;
+ Word16 shift_value;
+ Word32 fEnergy_log_fx, fEnergy_log_fx1;
+ fEnergy_exp = 0;
+ move16();
+ /*For 1e-12f in Q63*/
+ Word32 fWeight_fx;
+ Word64 Wmult_value;
+ Word16 exp_pow = 0;
+ move16();
+ Word16 guard_bits = find_guarded_bits_fx( piBandwidths[b] + 1 );
+ // fEnergy_f64 = W_shr( fEnergy_f64, ( 63 - ( 2 * ( q_final - guard_bits ) + 1 ) ) );
+ fEnergy_fx = 1180591616;
+ fEnergy_exp = -39;
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ Wmult_value = W_add( W_mult_32_32( L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ) ), W_mult_32_32( L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ) ) );
+ shift_value = W_norm( Wmult_value );
+ mul_32 = W_extract_h( W_shl( Wmult_value, shift_value ) );
+ mul_exp = 31 - ( 2 * ( q_final - guard_bits ) + 1 + shift_value - 32 );
+ fEnergy_fx = BASOP_Util_Add_Mant32Exp( fEnergy_fx, fEnergy_exp, mul_32, mul_exp, &fEnergy_exp ); // Some large number to prevent clipping
+ iFBOffset++;
+ }
+ IF( EQ_32( fEnergy_fx, 0 ) )
+ {
+ // f2me( 1e-12f, &fEnergy_fx, &fEnergy_exp ); //
+ fEnergy_fx = 1180591616;
+ fEnergy_exp = -39;
+ fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2
+ ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx;
+ move32();
+ ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp;
+ move16();
+ fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2
+ ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx;
+ move32();
+ ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp;
+ move16();
+ fEnergy_log_fx1 = -1006632960; // Q23
+ fWeight_fx = 403727488; // Q31
+ exp_pow = 0;
+ }
+ ELSE
+ {
+ fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2
+ ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx;
+ move32();
+ ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp;
+ move16();
+ fEnergy_fx = BASOP_Util_Log2( fEnergy_fx );
+ move32();
+ fEnergy_log_fx = L_add( fEnergy_fx, L_shl( L_deposit_l( fEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ // log2f( fEnergy )
+ fEnergy_log_fx1 = Mpy_32_32( fEnergy_log_fx, constant );
+ fEnergy_log_fx = L_sub( fEnergy_log_fx1, c_afThreshQuiet48_fx[b] ); // Q23 of ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) )
+ fWeight_fx = Mpy_32_32( 48509336, fEnergy_log_fx ); // 0.0068f*3.3219 in Q31, result in Q23
+ fWeight_temp = BASOP_util_Pow2( fWeight_fx, 8, &exp_pow );
+ fWeight_fx = Mpy_32_32( 708669604, fWeight_temp ); // 708669604 = Q31 0f 0.33
+ }
+ Flag1 = BASOP_Util_Cmp_Mant32Exp( fWeight_fx, exp_pow, const_comp3, exp3 );
+ IF( NE_16( Flag1, 1 ) )
+ {
+ fWeight_fx = const_comp3;
+ move32();
+ exp_pow = exp3;
+ move16();
+ }
+ Flag2 = BASOP_Util_Cmp_Mant32Exp( const_comp1, exp1, fWeight_fx, exp_pow );
+ IF( NE_16( Flag2, 1 ) )
+ {
+ fWeight_fx = const_comp1;
+ move32();
+ exp_pow = exp1;
+ move16();
+ }
+ Flag3 = BASOP_Util_Cmp_Mant32Exp( fMaxWeight_fx, fMaxWeight_exp, fWeight_fx, exp_pow );
+ IF( NE_16( Flag3, 1 ) )
+ {
+ fMaxWeight_fx = fWeight_fx;
+ move32();
+ fMaxWeight_exp = exp_pow;
+ move16();
+ }
+#ifdef APPLY_TEMPORAL_SMOOTHING
+ if ( k > 0 )
+ {
+ float fSmoothEnergy;
+ fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy;
+
+ fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy;
+ }
+#endif
+ ppfWeight_man[k][iChanOffset + b] = fWeight_fx;
+ ppfWeight_exp[k][iChanOffset + b] = exp_pow;
+ ppfBandEnergydB_fx[k][iChanOffset + b] = fEnergy_log_fx1; // Q23
+ }
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ ppfWeight_man[k][iChanOffset + b] = L_deposit_h( BASOP_Util_Divide3232_Scale( ppfWeight_man[k][iChanOffset + b], fMaxWeight_fx, &div_exp ) );
+ ppfWeight_exp[k][iChanOffset + b] = div_exp + ppfWeight_exp[k][iChanOffset + b] - fMaxWeight_exp;
+ }
+ }
+ }
+ /* fclose( fp );
+ fclose( fp1 );*/
+ return;
+}
+/*-------------------------------------------------------------------*
+ * Function ComputeMergeRMS()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void ComputeMergeRMS(
+ const Word32 iNumBands,
+ const Word32 iStartBlock,
+ const Word32 iGroupLength,
+ Word32 *pfMergedEnergydB,
+ Word32 *piQRMSEnvelope,
+ Word32 **ppfBandEnergy_man,
+ Word16 **ppfBandEnergy_exp )
+{
+ Word32 b;
+ /* FILE *fp = fopen( "float_fGroupEnergy.txt","ab+" );
+ FILE *fp1 = fopen( "fixed_fGroupEnergy.txt","ab+" );*/
+ Word32 constant = 1616142483; // Q29 of(1/log2(10))*10 // Note epsolon was added when computing BandEnergy;
+ move32();
+ Word32 fGroupEnergy32_fx;
+
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 n;
+ Word32 fGroupEnergy_fx = 0;
+ move32();
+ Word16 fGroupEnergy_exp = 0;
+ move16();
+ Word32 fRMSEnvelope_fx;
+ Word32 iQRMSEnvelope_fx;
+ FOR( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ )
+ {
+ fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[n][b], ppfBandEnergy_exp[n][b], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp );
+ }
+ fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[iGroupLength] ); // Division by iGroupLength
+ move32();
+ IF( NE_32( fGroupEnergy_fx, 0 ) )
+ {
+ fRMSEnvelope_fx = BASOP_Util_Log2( fGroupEnergy_fx );
+ move32();
+ fRMSEnvelope_fx = L_add( fRMSEnvelope_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
+ }
+ ELSE
+ {
+ fRMSEnvelope_fx = 0;
+ fGroupEnergy_exp = 0;
+ }
+ iQRMSEnvelope_fx = ( fRMSEnvelope_fx > 0 ) ? L_add( fRMSEnvelope_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fRMSEnvelope_fx ), ONE_IN_Q24 ) );
+ iQRMSEnvelope_fx = L_shr( iQRMSEnvelope_fx, 25 );
+
+ fGroupEnergy32_fx = fRMSEnvelope_fx; /*Q25*/ // BASOP_Util_Log2( fGroupEnergy_fx );
+ fGroupEnergy32_fx = Mpy_32_32( fGroupEnergy32_fx, constant ); // Q23
+ pfMergedEnergydB[b] = fGroupEnergy32_fx; // Q23
+ piQRMSEnvelope[b] = iQRMSEnvelope_fx; // Q25
+ }
+ return;
+}
+/*-------------------------------------------------------------------*
+ * Function ComputeRMSEnvelopeBits()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static Word32 ComputeRMSEnvelopeBits(
+ const Word32 iChannels,
+ const Word32 iNumBands,
+ const Word32 *piQRMSEnevelope )
+{
+ Word32 n;
+ Word32 iRMSEnvelopeBits = 0;
+ move32();
+ Word32 iChanOffset = 0;
+ move32();
+
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 b;
+ Word32 iLastRMSVal;
+
+ iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, ENV0_BITS );
+ iLastRMSVal = piQRMSEnevelope[iChanOffset];
+ move32();
+ FOR( b = 1; b < iNumBands; b++ )
+ {
+ Word32 iDelta;
+
+ iDelta = L_sub( piQRMSEnevelope[iChanOffset + b], iLastRMSVal );
+ iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN;
+ iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX;
+ iDelta = L_sub( iDelta, ENV_DELTA_MIN );
+ iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, c_aaiRMSEnvHuffEnc[iDelta][0] );
+
+ iLastRMSVal = piQRMSEnevelope[iChanOffset + b];
+ move32();
+ }
+
+ iChanOffset = L_add( iChanOffset, iNumBands );
+ }
+
+ return iRMSEnvelopeBits;
+}
+/*-------------------------------------------------------------------*
+ * Function ComputeSNRPenalty()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static Word32 ComputeSNRPenalty(
+ const Word32 iChannels,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ const Word32 iStartBlock,
+ const Word32 iGroupLength,
+ Word32 **ppfBandEnergy_dB_fx,
+ const Word32 *piRMSEnvelope,
+ Word16 *fSNRPenalty_exp )
+{
+ Word32 n;
+ Word32 iChanOffset;
+ Word32 temp;
+ Word32 fSNRPenalty_fx = 0;
+ move32();
+ Word32 fSNRPenaltyconst_fx = 0;
+ move32();
+ Word32 mul_temp;
+ Word16 fSNRPenaltycnst_exp = 0, exp = 0;
+ /*FILE *fp = fopen( "float_SNRpenalty.txt", "ab+" );
+ FILE *fp1 = fopen( "fixed_SNRpenalty.txt", "ab+" );*/
+ // f2me( 1e10f, &fSNRPenaltyconst_fx, &fSNRPenaltycnst_exp );//
+ /*For 1e10f*/
+ fSNRPenaltyconst_fx = 1250000000;
+ fSNRPenaltycnst_exp = 34;
+ iChanOffset = 0;
+ move32();
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 b;
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 k;
+ Word32 fRMSVal_fx;
+ Word32 RMS_value_fx;
+ // RMS_value = piRMSEnvelope[iChanOffset + b];
+ RMS_value_fx = L_shl( piRMSEnvelope[iChanOffset + b], 25 );
+ move32();
+ // fRMSVal = 3.0103f * (float) RMS_value;
+ fRMSVal_fx = Mpy_32_32( 1616142506, RMS_value_fx ); // Q23
+ move32();
+ FOR( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ )
+ {
+ Word32 fDeltadB_fx;
+ fDeltadB_fx = L_sub( fRMSVal_fx, ppfBandEnergy_dB_fx[k][iChanOffset + b] );
+ IF( LT_32( fDeltadB_fx, -75756680 ) )
+ {
+ fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, fSNRPenaltyconst_fx, fSNRPenaltycnst_exp, fSNRPenalty_exp ); // Some large number to prevent clipping
+ }
+ ELSE
+ {
+ mul_temp = L_abs( L_sub( Mpy_32_32( c_fiDefaultTheta48_fx[b], fDeltadB_fx ), fDeltadB_fx ) );
+ temp = Mpy_32_32( mul_temp, Mpy_32_32( 715827883, L_shl( piBandwidths[b], 27 ) ) ); // Q27+23 -31=19
+ exp = Q12; // Q31 - Q19
+ fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, temp, exp, fSNRPenalty_exp );
+ }
+ }
+ }
+
+ iChanOffset = L_add( iChanOffset, iNumBands );
+ }
+ // fprintf( fp,"%f\n", fSNRPenalty );
+ // fprintf( fp1,"%f\n", fSNRPenalty );
+ /* fclose( fp );
+ fclose( fp1 );*/
+ return fSNRPenalty_fx;
+}
+/*-------------------------------------------------------------------*
+ * Function TryMerge2()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static Word32 TryMerge2(
+ const Word32 iChannels,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 **ppfBandEnergy_man,
+ Word16 **ppfBandEnergy_exp,
+ Word32 **ppfBandEnergydB_fx,
+ GMNode *psGMNode1,
+ GMNode *psGMNode2,
+ Word16 *fMergedCost_exp )
+{
+ Word32 iRMSEnvBits1;
+ Word32 iRMSEnvBits2;
+ Word32 iRMSEnvBitsMerged;
+ Word32 temp = 0;
+ move32();
+ Word16 temp_exp = 0;
+ move16();
+ Word32 fMergedCost_fx = 0;
+ move32();
+ Word32 RMSEnvBits_fx;
+ Word32 fSNRPenalty1_fx;
+ Word32 fSNRPenalty2_fx;
+ Word32 fSNRPenaltyMerged_fx;
+ Word16 fSNRPenalty1_exp = 0;
+ move16();
+ Word16 fSNRPenalty2_exp = 0;
+ move16();
+ Word16 fSNRPenaltyMerged_exp = 0;
+ move16();
+ Word32 one_in_mant = L_negate( ONE_IN_Q30 );
+ Word16 one_in_exp = 1;
+ move16();
+ *fMergedCost_exp = 0;
+ move16();
+ Word16 flag = 0;
+ move16();
+ IF( EQ_32( psGMNode1->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode1->fGroupSNRPenalty_exp, one_in_exp ) )
+ {
+ flag = 1;
+ move16();
+ }
+ /* First compute current RMS Envelope for each group */
+ IF( EQ_32( psGMNode1->iGroupRMSEnvelopeCost, -1 ) || flag )
+ {
+ ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp );
+ iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope );
+ fSNRPenalty1_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenalty1_exp );
+ psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1;
+ move32();
+ psGMNode1->fGroupSNRPenalty_fx = fSNRPenalty1_fx;
+ move32();
+ psGMNode1->fGroupSNRPenalty_exp = fSNRPenalty1_exp;
+ move16();
+ }
+ ELSE
+ {
+ iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost;
+ move32();
+ fSNRPenalty1_fx = psGMNode1->fGroupSNRPenalty_fx;
+ move32();
+ fSNRPenalty1_exp = psGMNode1->fGroupSNRPenalty_exp;
+ move16();
+ }
+ IF( EQ_32( psGMNode2->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode2->fGroupSNRPenalty_exp, one_in_exp ) )
+ {
+ flag = 1;
+ move16();
+ }
+ IF( EQ_32( psGMNode2->iGroupRMSEnvelopeCost, -1 ) || flag )
+ {
+
+ ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, psGMNode2->pfMergedEnergydB_fx, psGMNode2->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp );
+ iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope );
+ fSNRPenalty2_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode2->piQRMSEnvelope, &fSNRPenalty2_exp );
+ psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2;
+ move32();
+ psGMNode2->fGroupSNRPenalty_fx = fSNRPenalty2_fx;
+ move32();
+ psGMNode2->fGroupSNRPenalty_exp = fSNRPenalty2_exp;
+ move16();
+ }
+ ELSE
+ {
+ iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost;
+ move32();
+ fSNRPenalty2_fx = psGMNode2->fGroupSNRPenalty_fx;
+ move32();
+ fSNRPenalty2_exp = psGMNode2->fGroupSNRPenalty_exp;
+ move16();
+ }
+ ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp );
+
+ /* Compute the RMS Envelope cost for merged group */
+ iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope );
+ // fSNRPenalty_exp = 0;
+ /* Compute an approximation of the bit cost based on SNR increase/decrease due to merging */
+ fSNRPenaltyMerged_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenaltyMerged_exp );
+ RMSEnvBits_fx = L_sub( L_sub( iRMSEnvBitsMerged, iRMSEnvBits1 ), iRMSEnvBits2 );
+ RMSEnvBits_fx = L_shl( RMSEnvBits_fx, 10 ); // Converting to Q10
+ temp = BASOP_Util_Add_Mant32Exp( fSNRPenaltyMerged_fx, fSNRPenaltyMerged_exp, L_negate( fSNRPenalty1_fx ), fSNRPenalty1_exp, &temp_exp );
+ fMergedCost_fx = BASOP_Util_Add_Mant32Exp( temp, temp_exp, L_negate( fSNRPenalty2_fx ), fSNRPenalty2_exp, fMergedCost_exp );
+ fMergedCost_fx = BASOP_Util_Add_Mant32Exp( fMergedCost_fx, *fMergedCost_exp, RMSEnvBits_fx, 21, fMergedCost_exp );
+ // fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2;
+ return fMergedCost_fx;
+}
+
+/*-------------------------------------------------------------------*
+ * Function ComputeGreedyGroups3()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void ComputeGreedyGroups3(
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
+ const int32_t iChannels,
+ const int32_t iNumBands,
+ const int32_t *piBandwidths,
+ const int32_t iMaxGroups )
+{
+
+ Word32 iDone = 0;
+ Word32 iNumGroups = psRMSEnvelopeGrouping->iMaxGroups;
+ WHILE( EQ_32( iDone, 0 ) )
+ {
+ GMNode *psGMNode;
+ GMNode *psBestGMNode;
+ /* Instead of 1e20f*/
+ Word32 fBestMergeCost_fx = 1455191552; // mantissa of 1e20f
+ move32();
+ Word16 fBestMergeCost_exp = 67; // exp of 1e20f
+ move16();
+ Word16 Flag = 0;
+ move16();
+ psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0];
+ psBestGMNode = NULL;
+ WHILE( psGMNode->psNext != NULL )
+ {
+ Word32 fMergeCost_fx = 0;
+ move32();
+ Word16 fMergeCost_exp = 0;
+ move16();
+ fMergeCost_fx = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psGMNode, psGMNode->psNext, &fMergeCost_exp );
+ IF( LT_32( fMergeCost_fx, 0 ) && ( GT_32( fBestMergeCost_fx, 0 ) ) )
+ {
+
+ Flag = 1;
+ move16();
+ }
+ ELSE IF( ( GT_32( fMergeCost_fx, 0 ) && ( LT_32( fBestMergeCost_fx, 0 ) ) ) )
+ {
+ Flag = -1;
+ move16();
+ }
+ ELSE
+ {
+ Flag = BASOP_Util_Cmp_Mant32Exp( fBestMergeCost_fx, fBestMergeCost_exp, fMergeCost_fx, fMergeCost_exp );
+ }
+ IF( EQ_32( Flag, 1 ) )
+ {
+ fBestMergeCost_fx = fMergeCost_fx;
+ move32();
+ fBestMergeCost_exp = fMergeCost_exp;
+ move16();
+ psBestGMNode = psGMNode;
+ }
+
+ psGMNode = psGMNode->psNext;
+ }
+
+ IF( ( GT_32( fBestMergeCost_fx, 0 ) && ( LE_32( iNumGroups, iMaxGroups ) ) ) )
+ {
+ iDone++;
+ }
+ ELSE IF( ( psBestGMNode != NULL ) && ( psBestGMNode->psNext != NULL ) )
+ {
+ psBestGMNode->iGroupLength = L_add( psBestGMNode->psNext->iGroupLength, psBestGMNode->iGroupLength );
+ psBestGMNode->fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 );
+ psBestGMNode->fGroupSNRPenalty_exp = 1;
+ move16();
+ psBestGMNode->psNext = psBestGMNode->psNext->psNext;
+ iNumGroups--;
+ }
+ ELSE
+ {
+ iDone++; // This only catches a problem
+ }
+ }
+ return;
+}
+/*-------------------------------------------------------------------*
+ * Function ComputeRMSEnvelope()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void ComputeRMSEnvelope(
+ const Word32 iChannels,
+ const Word32 iNumBands,
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ Word32 **ppfBandEnergy_man,
+ Word16 **ppfBandEnergy_exp,
+ Word32 ***pppiRMSEnvelope )
+{
+ Word32 n;
+ Word32 fGroupEnergy_fx;
+ Word16 fGroupEnergy_exp;
+ Word32 temp;
+ // FILE *fp = fopen( "RmsEnvelope_fixed", "ab+" );
+ // FILE *fp1 = fopen( "RmsEnvelope_float", "ab+" );
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 b;
+ Word32 iChanOffset;
+
+ iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) );
+
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 k;
+ Word32 iBlockOffset;
+ iBlockOffset = 0;
+ FOR( k = 0; k < iNumGroups; k++ )
+ {
+ Word32 m;
+ fGroupEnergy_exp = 0;
+ move16();
+ fGroupEnergy_fx = 0;
+ move32();
+ FOR( m = 0; m < piGroupLengths[k]; m++ )
+ {
+ fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[iBlockOffset][b + iChanOffset], ppfBandEnergy_exp[iBlockOffset][b + iChanOffset], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp );
+ iBlockOffset++;
+ }
+ fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[piGroupLengths[k]] ); // Division by iGroupLength
+ fGroupEnergy_fx = BASOP_Util_Log2( fGroupEnergy_fx );
+ move32();
+ fGroupEnergy_fx = L_add( fGroupEnergy_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
+ temp = ( fGroupEnergy_fx > 0 ) ? L_add( fGroupEnergy_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fGroupEnergy_fx ), ONE_IN_Q24 ) ); // Q25
+ temp = L_shr( temp, 25 );
+ temp = ( temp > ENV_MIN ) ? temp : ENV_MIN;
+ temp = ( temp < ENV_MAX ) ? temp : ENV_MAX;
+ pppiRMSEnvelope[n][k][b] = temp;
+ // fprintf( fp,"%d\n", pppiRMSEnvelope[n][k][b] );
+ }
+ }
+ }
+ // fclose( fp );
+ /* fclose( fp1 );*/
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * Function LimitRMSEnvelope()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static void LimitRMSEnvelope(
+ const Word32 iBandCount,
+ const Word32 iRMSDeltaMax,
+ const Word32 iRMSDeltaMin,
+ Word32 *piRMSEnvelope )
+{
+ Word32 iBand;
+ Word32 iLastSCF;
+
+ /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */
+ iLastSCF = piRMSEnvelope[iBandCount - 1];
+ move32();
+ for ( iBand = iBandCount - 2; iBand > -1; iBand-- )
+ {
+ Word32 iDelta;
+
+ iDelta = L_sub( iLastSCF, piRMSEnvelope[iBand] );
+
+ IF( GT_32( iDelta, iRMSDeltaMax ) )
+ {
+#ifdef DEBUG_VERBOSE
+ printf( "WARNING RMS envelope delta limited\n" );
+#endif
+ piRMSEnvelope[iBand] = L_add( L_sub( iDelta, iRMSDeltaMax ), piRMSEnvelope[iBand] );
+ }
+
+ iLastSCF = piRMSEnvelope[iBand];
+ move32();
+ }
+
+ /* Increase low envelope values to ensure that the envelope traces the large values correctly (checking for min deltas)*/
+ iLastSCF = piRMSEnvelope[0];
+ FOR( iBand = 1; iBand < iBandCount; iBand++ )
+ {
+ Word32 iDelta;
+
+ iDelta = L_sub( piRMSEnvelope[iBand], iLastSCF );
+
+ IF( LT_32( iDelta, iRMSDeltaMin ) )
+ {
+#ifdef DEBUG_VERBOSE
+ printf( "WARNING RMS envelope delta limited\n" );
+#endif
+ piRMSEnvelope[iBand] = L_add( piRMSEnvelope[iBand], L_sub( iRMSDeltaMin, iDelta ) );
+ }
+
+ iLastSCF = piRMSEnvelope[iBand];
+ move32();
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * Function ComputeEnvelopeGrouping()
+ *
+ *
+ *-------------------------------------------------------------------*/
+void ComputeEnvelopeGrouping(
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
+ const Word32 iChannels,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx,
+ Word32 *piNumGroups,
+ Word32 *piGroupLengths,
+ Word32 ***pppiRMSEnvelope,
+ Word16 q_final )
+{
+ Word32 n;
+ GMNode *psGMNode;
+
+ /* Compute Band Energies */
+ ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal_fx, pppfImag_fx, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psRMSEnvelopeGrouping->ppfWeight_man, psRMSEnvelopeGrouping->ppfWeight_exp, q_final );
+ /* Init GMNodes */
+ psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0;
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2;
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL;
+ psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1;
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 );
+ psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_exp = 1;
+ move16();
+ FOR( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ )
+ {
+ psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n];
+ psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = L_shl( n, 1 );
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2;
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1;
+ move32();
+ psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 );
+ psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1;
+ move16();
+ psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL;
+ }
+ /* Perform grouping via Greedy Merge */
+ /* Allows control over max groups can call using 16 if want same as previous call */
+ ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->iNumBlocks );
+ /* Calc Groups from Merge Results */
+ *piNumGroups = 0;
+ move32();
+ psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0];
+ WHILE( psGMNode != NULL )
+ {
+ piGroupLengths[*piNumGroups] = psGMNode->iGroupLength;
+ move32();
+ *piNumGroups = L_add( *piNumGroups, 1 );
+ psGMNode = psGMNode->psNext;
+ }
+ /* Compute RMS Envelope given group lengths */
+ ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, pppiRMSEnvelope );
+
+ /* Envelope Tenting */
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < *piNumGroups; k++ )
+ {
+ LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] );
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h
new file mode 100644
index 0000000000000000000000000000000000000000..72ff5b892685f218c107b043b09886c17c413e10
--- /dev/null
+++ b/lib_isar/isar_cnst.h
@@ -0,0 +1,159 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_CNST_H
+#define ISAR_CNST_H
+
+#include
+#include "options.h"
+
+/* clang-format off */
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+
+/*----------------------------------------------------------------------------------*
+ * Split Binaural Rendering Constants
+ *----------------------------------------------------------------------------------*/
+
+typedef enum
+{
+ PCM_INT16,
+ PCM_FLOAT32,
+ PCM_NOT_KNOW = 0xffff
+} PCM_RESOLUTION;
+
+typedef enum
+{
+ ANY_YAW,
+ PITCH_ONLY,
+ ANY_ROLL,
+ PRED_ONLY,
+ PRED_ROLL_ONLY,
+ COM_GAIN_ONLY,
+ LR_GAIN_ONLY
+} ISAR_SPLIT_REND_POSE_TYPE;
+
+
+#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */
+
+#define SPLIT_REND_MAX_YAW_ONLY_POSES 2
+#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2
+#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2
+#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2
+#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/
+#define MAX_EXTRAPOLATION_ANGLE_Q22 (62914560) /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/
+
+#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES )
+#define MAX_SPLIT_REND_MD_BANDS 20
+#define MAX_SPLIT_MD_SUBFRAMES 1
+#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+#define COMPLEX_MD_BAND_THRESH_LOW 4
+#define COMPLEX_MD_BAND_THRESH_HIGH 10
+#else
+#define COMPLEX_MD_BAND_THRESH_LOW 5
+#endif
+#define SPLIT_REND_RO_MD_BAND_THRESH 4
+
+#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL 6
+#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL 5
+#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL 5
+#define ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL 4
+
+#define ISAR_SPLIT_REND_PRED_MIN_VAL_Q30 -1503238553 //Q30
+#define ISAR_SPLIT_REND_PRED_MAX_VAL_Q30 1503238553 //Q30
+
+#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4
+#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63
+#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31
+#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31
+#define ISAR_SPLIT_REND_D_QUANT_PNTS 15
+#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f
+#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f
+
+#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f
+#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f
+#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30 (1<<29) //0.5f in Q30
+#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30 1610612736 //1.5f in Q30
+#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS
+#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f
+#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f
+#define ISAR_SPLIT_REND_D_MIN_VAL_FX 0 //Q31
+#define ISAR_SPLIT_REND_D_MAX_VAL_FX MAX_32 //Q31
+
+#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) )
+#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 200431807
+#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26 719023543
+#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
+#define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) )
+#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
+#define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) )
+#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) )
+
+#define ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31 200431807
+#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26 719023543
+#define ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31 96983132
+#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26 1485981989
+
+#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) )
+#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) )
+#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) )
+#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) )
+#define ISAR_SPLIT_REND_D_Q_STEP_Q31 153391689
+#define ISAR_SPLIT_REND_D_1BYQ_STEP_Q27 (14 << 27) //Q27
+#define ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31 153391689
+#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27 (14 << 27) //Q27
+
+
+#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9
+#define ISAR_SPLIT_REND_DOF_BITS 2
+#define ISAR_SPLIT_REND_HQ_MODE_BITS 1
+#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3
+#define ISAR_SPLIT_REND_RO_FLAG_BITS 1
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2
+#endif
+/*----------------------------------------------------------------------------------*
+ * Split rendering bitrate constants
+ *----------------------------------------------------------------------------------*/
+
+#define SPLIT_REND_256k 256000
+#define SPLIT_REND_320k 320000
+#define SPLIT_REND_384k 384000
+#define SPLIT_REND_512k 512000
+#define SPLIT_REND_768k 768000
+
+#endif /*SPLIT_REND_WITH_HEAD_ROT */
+
+#endif /*ISAR_CNST_H */
+/* clang-format on */
diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..32e30e97c418237df357063331468fb3f72f0209
--- /dev/null
+++ b/lib_isar/isar_lc3plus_common.c
@@ -0,0 +1,89 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "options.h"
+#include "isar_lc3plus_common.h"
+#include "ivas_error.h"
+#include "lc3.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*-----------------------------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_LC3plusErrToIvasErr()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr(
+ const LC3PLUS_Error lc3PlusError )
+{
+ switch ( lc3PlusError )
+ {
+ case LC3PLUS_OK:
+ return IVAS_ERR_OK;
+ case LC3PLUS_BITRATE_ERROR:
+ return IVAS_ERR_LC3PLUS_INVALID_BITRATE;
+ default:
+ break;
+ }
+
+ return IVAS_ERR_INTERNAL;
+}
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError )
+{
+ switch ( lc3PlusRtpError )
+ {
+ case LC3PLUS_RTP_ERR_NO_ERROR:
+ return IVAS_ERR_OK;
+ case LC3PLUS_RTP_ERR_NULL_PTR:
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ case LC3PLUS_RTP_ERR_INVALID_PARAMETERS:
+ return IVAS_ERR_WRONG_PARAMS;
+ case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED:
+ return IVAS_ERR_NOT_IMPLEMENTED;
+ case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION:
+ return IVAS_ERR_INTERNAL;
+ case LC3PLUS_RTP_ERR_INVALID_BITSTREAM:
+ return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM;
+ case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE:
+ return IVAS_ERR_INVALID_BUFFER_SIZE;
+ case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED:
+ return IVAS_ERR_INTERNAL;
+ case LC3PLUS_RTP_ERR_GENERIC_ERROR:
+ default:
+ break;
+ }
+
+ return IVAS_ERR_UNKNOWN;
+}
+#endif
+#endif
diff --git a/lib_isar/isar_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..08ffff60a7d2a612691605338f274f864050feaf
--- /dev/null
+++ b/lib_isar/isar_lc3plus_common.h
@@ -0,0 +1,72 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_LC3PLUS_COM_H
+#define ISAR_LC3PLUS_COM_H
+
+
+#include
+#include "options.h"
+#include "ivas_error.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "lc3.h"
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+#include "isar_lc3plus_payload.h"
+#endif
+
+/*! common configuration parameters between encoder and decoder */
+typedef struct LC3PLUS_CONFIG
+{
+ /*! frame duration in microseconds [10000, 5000, 2500] */
+ int16_t lc3plus_frame_duration_us;
+ /*! isar frame duration in microseconds [20000, 10000, 5000] */
+ int16_t isar_frame_duration_us;
+ /*! sampling rate*/
+ int32_t samplerate;
+ /*! number of channels */
+ int16_t channels;
+#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS || defined ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /*! high resolution mode enabled (1) or disabled (0)*/
+ int16_t high_res_mode_enabled;
+#endif
+} LC3PLUS_CONFIG;
+
+/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */
+ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError );
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */
+ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError );
+#endif
+
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
+#endif /* ISAR_LC3PLUS_COM_H */
diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c63158b3f3c3b9230cd30cd4e67741dbe13d1c5
--- /dev/null
+++ b/lib_isar/isar_lc3plus_dec.c
@@ -0,0 +1,857 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#include "prot.h"
+#include "ivas_prot.h"
+#include "isar_lc3plus_dec.h"
+#include "isar_lc3plus_common.h"
+#include "lc3.h"
+#include "ivas_error_utils.h"
+#include "wmc_auto.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*-------------------------------------------------------------------------
+ * isar_LC3PLUS_AllocateSubframeDecodingMatrix()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix(
+ int16_t **subframeChannelMatrix )
+{
+ for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ free( subframeChannelMatrix[i] );
+ }
+
+ free( subframeChannelMatrix );
+
+ return;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_Open()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_Open(
+ const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */
+ ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
+)
+{
+ LC3PLUS_Error err;
+ int32_t decoder_size;
+ Word32 scratch_size;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t i;
+
+ if ( 0 == config.lc3plus_frame_duration_us )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" );
+ }
+#else
+ int16_t lc3plusFrameIdx;
+ int16_t numLC3plusFramesPerIvasFrame;
+ int16_t i;
+#endif
+
+ if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS )
+ {
+ return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" );
+ }
+#else
+
+ if ( 0 == config.lc3plus_frame_duration_us )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" );
+ }
+ numLC3plusFramesPerIvasFrame = (int16_t) ( config.isar_frame_duration_us / config.lc3plus_frame_duration_us );
+#endif
+
+
+ ( *handle )->num_decs = 0;
+ ( *handle )->pcm_conversion_buffer = NULL;
+ ( *handle )->handles = NULL;
+ ( *handle )->selective_decoding_states = NULL;
+ ( *handle )->bitstream_caches = NULL;
+
+ if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+
+ if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+
+ for ( i = 0; i < config.channels; ++i )
+ {
+ ( *handle )->handles[i] = NULL;
+ ( *handle )->selective_decoding_states[i] = NULL;
+ }
+
+ if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+ for ( i = 0; i < config.channels; ++i )
+ {
+ ( *handle )->bitstream_caches[i] = NULL;
+ }
+
+ ( *handle )->num_decs = config.channels;
+ for ( int32_t iCh = 0; iCh < config.channels; iCh++ )
+ {
+ ( *handle )->selective_decoding_states[iCh] = NULL;
+ if ( NULL != ( *handle )->bitstream_caches )
+ {
+ ( *handle )->bitstream_caches[iCh] = NULL;
+ }
+ /* allocate and configure LC3plus decoder */
+ decoder_size = lc3plus_dec_get_size( config.samplerate, 1, LC3PLUS_PLC_ADVANCED );
+ if ( 0 == decoder_size )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" );
+ }
+
+ if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled );
+#else
+ err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 );
+#endif
+ if ( LC3PLUS_OK != err )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" );
+ }
+
+ err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
+ if ( LC3PLUS_OK != err )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" );
+ }
+
+ /* allocate and configure per LC3plus decoder skip state */
+ if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
+ }
+#endif
+
+ ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0;
+ ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE;
+#else
+ for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ )
+ {
+ ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE;
+ }
+#endif
+
+ /* allocate and configure per LC3plus decoder bitstream cache */
+ if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/;
+#else
+ ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame;
+#endif
+ if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" );
+ }
+ ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0;
+ }
+
+ ( *handle )->config = config;
+ if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" );
+ }
+
+ if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" );
+ }
+
+ scratch_size = lc3plus_dec_get_scratch_size( ( *handle )->handles[0] );
+ if ( ( ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size ) ) == NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper scratch\n" );
+ }
+
+ return IVAS_ERR_OK;
+}
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
+ int16_t ***subframeChannelMatrix,
+ const uint32_t num_decs )
+{
+ int16_t i;
+
+ if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" );
+ }
+
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ ( *subframeChannelMatrix )[i] = NULL;
+ }
+
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL )
+ {
+ isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" );
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
+ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] )
+{
+ int16_t numIvasSubFramesPerLC3frame;
+ uint32_t decIdx;
+ int16_t ivasSubframeIdx;
+ int16_t effectiveIsarSubframeDuration;
+ int16_t actual_num_spatial_subframes;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" );
+ }
+
+ if ( NULL == subframeChannelMatrix )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" );
+ }
+
+ if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid isar_frame_duration_us/lc3plus_frame_duration_us values\n" );
+ }
+
+ effectiveIsarSubframeDuration = (int16_t) ( handle->config.isar_frame_duration_us == 20000 ? handle->config.isar_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.isar_frame_duration_us );
+ numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIsarSubframeDuration;
+ actual_num_spatial_subframes = (int16_t) handle->config.isar_frame_duration_us / effectiveIsarSubframeDuration;
+ /* 0.5(0) = 10ms lc3plus, 5ms subframe */
+ if ( numIvasSubFramesPerLC3frame != 1 )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" );
+ }
+
+ /* map subframeChannelMatrix to lc3plus skip states */
+ /* 1st pass: Flag the required frames */
+ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ )
+ {
+ for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ )
+ {
+ if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] )
+ {
+ /* subframe needed by the user, definitely decode */
+ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE;
+ }
+ else
+ {
+
+ /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */
+ if (
+ ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] )
+ {
+ /* ... but if the following subframe is required, it needs to be decoded and dropped */
+ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP;
+ }
+ else
+ {
+ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP;
+ }
+ }
+ }
+ }
+
+ /* if a decoder was paused before, it needs to either:
+ * - Decode the cached frame (if available) and the first required frame OR
+ * - Decode the previous LC3plus subframe, even if it isn't needed by the user */
+ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ )
+ {
+ if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame )
+ {
+ /* find the first frame required by the user */
+ for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ )
+ {
+ if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] )
+ {
+ /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */
+ if ( 0 == ivasSubframeIdx )
+ {
+ handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1;
+ break;
+ }
+ /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/
+ else
+ {
+ handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */
+ for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ )
+ {
+ for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ )
+ {
+ if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE )
+ {
+ handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE;
+ }
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_GetDelay()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_GetDelay(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
+ int32_t *delayInSamples /* o : decoder delay in number of samples per channel */
+)
+{
+ int32_t tmpDelayInSamples;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" );
+ }
+ if ( NULL == delayInSamples )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" );
+ }
+
+ *delayInSamples = 0;
+ /* sanity check whether all encoders are actually configured identically */
+ for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ )
+ {
+ if ( NULL == handle->handles[iDec] )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" );
+ }
+
+ tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] );
+ if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" );
+ }
+
+ *delayInSamples = tmpDelayInSamples;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_Close()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void ISAR_LC3PLUS_DEC_Close(
+ ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */
+)
+{
+ if ( NULL == handle || NULL == *handle )
+ {
+ return;
+ }
+ for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ )
+ {
+ if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] )
+ {
+ free( ( *handle )->handles[iDec] );
+ }
+
+ if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] )
+ {
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ free( ( *handle )->selective_decoding_states[iDec]->frame_actions );
+#endif
+ free( ( *handle )->selective_decoding_states[iDec] );
+ }
+
+ if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] )
+ {
+ free( ( *handle )->bitstream_caches[iDec]->bitstream_cache );
+ free( ( *handle )->bitstream_caches[iDec] );
+ }
+ }
+
+ if ( NULL != ( *handle )->pcm_conversion_buffer )
+ {
+ free( ( *handle )->pcm_conversion_buffer );
+ }
+ if ( NULL != ( *handle )->scratch )
+ {
+ free( ( *handle )->scratch );
+ }
+
+ free( ( *handle )->handles );
+
+ if ( NULL != ( *handle )->bitstream_caches )
+ {
+ free( ( *handle )->bitstream_caches );
+ }
+ free( ( *handle )->selective_decoding_states );
+
+ free( *handle );
+ *handle = NULL;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * decode_or_conceal_one_lc3plus_frame()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static ivas_error decode_or_conceal_one_lc3plus_frame(
+ LC3PLUS_Dec *dec,
+ uint8_t *bitstream_in,
+ const int32_t bitstream_in_length,
+ int16_t **pcm_out_buffer,
+ const int32_t badFrameIndicator,
+ uint8_t *scratch )
+{
+ LC3PLUS_Error err;
+
+ push_wmops( "lc3plus_dec16" );
+ err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, scratch, badFrameIndicator );
+ pop_wmops();
+
+ if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator )
+ {
+ /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */
+ err = LC3PLUS_OK;
+ }
+
+ if ( err != LC3PLUS_OK )
+ {
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" );
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * isar_LC3PLUS_DEC_Decode_or_Conceal_internal()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
+ uint8_t *bitstream_in, /* i : pointer to input bitstream */
+ int32_t bitstream_in_size, /* i : size of bitstream_in */
+ const int16_t badFrameIndicator, /* i : bad frame indicator. If set to 1, triggers concealment */
+ Word32 **pcm_out /* o : decoded samples */
+)
+{
+ uint32_t iDec;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t config_num_media_times;
+ int32_t iMediaTime;
+ int32_t iFtd;
+ LC3PLUS_RTP_PAYLOAD payload;
+#else
+ int32_t iLc3plusFrame;
+ int32_t lc3framesPerIvasFrame;
+ int32_t bitstreamOffsetPerCoder;
+ uint8_t *bitstream_in_iter = bitstream_in;
+#endif
+ int32_t ivasSampleIndex;
+ int16_t numSamplesPerLC3plusChannel;
+ ivas_error err;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" );
+ }
+ if ( NULL == bitstream_in )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" );
+ }
+ if ( NULL == pcm_out )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" );
+ }
+ if ( badFrameIndicator != 0 && badFrameIndicator != 1 )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" );
+ }
+ if ( badFrameIndicator == 0 && bitstream_in_size <= 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" );
+ }
+
+ if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+ if ( !badFrameIndicator )
+ {
+ if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" );
+ }
+ if ( payload.sampling_rate_hz != handle->config.samplerate )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" );
+ }
+ if ( payload.num_channels != handle->config.channels )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" );
+ }
+ if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" );
+ }
+ if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" );
+ }
+ if ( payload.num_media_times != config_num_media_times )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" );
+ }
+ }
+#endif
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times );
+ for ( iDec = 0; iDec < handle->num_decs; iDec++ )
+ {
+ for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ )
+ {
+ iFtd = iDec + iMediaTime * handle->num_decs;
+#else
+ lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+
+ numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame );
+ bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame;
+ for ( iDec = 0; iDec < handle->num_decs; iDec++ )
+ {
+ for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ )
+ {
+#endif
+ if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame )
+ {
+ if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "LC3plus cache is empty\n" );
+ }
+
+ err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], handle->bitstream_caches[iDec]->bitstream_cache, handle->bitstream_caches[iDec]->bitstream_cache_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch );
+ if ( err != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( err, "lc3plus decoding failed\n" );
+ }
+ handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0;
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
+ }
+
+ /* reset cache if caching is enabled - it has either been decoded or is not needed */
+ if ( NULL != handle->bitstream_caches )
+ {
+ handle->bitstream_caches[iDec]->bitstream_cache_size = 0;
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ switch ( handle->selective_decoding_states[iDec]->frame_action )
+#else
+ switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] )
+#endif
+ {
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ case DEC_ACTION_DECODE_AND_DROP:
+ {
+ err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch );
+ if ( err != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( err, "lc3plus decoding failed\n" );
+ }
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
+ break;
+ }
+#endif
+ case DEC_ACTION_DECODE_AND_USE:
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( badFrameIndicator )
+ {
+ err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch );
+ }
+ else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD )
+ {
+ return IVAS_ERR_NOT_IMPLEMENTED;
+ /* Untested therefore disabled. Would probably only need to call concealment,
+ * but the LC3plus API requires a non-NULL ptr for this which is not available here */
+ }
+ else
+ {
+ err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch );
+ }
+ if ( err != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( err, "lc3plus decoding failed\n" );
+ }
+
+ for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ )
+ {
+ ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel;
+ pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16];
+ }
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
+ break;
+#else
+ err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator );
+ if ( err != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( err, "lc3plus decoding failed\n" );
+ }
+
+ for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ )
+ {
+ ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel;
+ pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16];
+ }
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0;
+ break;
+#endif
+ }
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ case DEC_ACTION_SKIP:
+ {
+ /* log that this instance has skipped a frame and must decode twice once reactivated */
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
+ break;
+ }
+#endif
+ case DEC_ACTION_CACHE:
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" );
+ }
+ /* store bit rate of cached frame */
+ mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length );
+ handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length;
+ /* log that this instance has skipped a frame and must decode twice once reactivated */
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
+ break;
+#else
+ if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" );
+ }
+ /* store bit rate of cached frame */
+ mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder );
+ handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder;
+ /* log that this instance has skipped a frame and must decode twice once reactivated */
+ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1;
+ break;
+#endif
+ }
+ case DEC_ACTION_NUM_ENUMS:
+ default:
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ } /* for each media time */
+ /* reset skipping state, must be set by the user before each decode call*/
+ handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE;
+ } /* for each dec/channel */
+#else
+
+ bitstream_in_iter += bitstreamOffsetPerCoder;
+ }
+
+ /* reset skipping state, must be set by the user before each decode call*/
+ for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ )
+ {
+ handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE;
+ }
+ }
+
+#endif
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_Decode()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_Decode(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */
+ uint8_t *bitstream_in, /* i : pointer to input bitstream */
+ const int32_t bitstream_in_size, /* i : size of bitstream_in */
+ Word32 **pcm_out /* o : decoded samples */
+)
+{
+ int16_t badFrameIndicator;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" );
+ }
+ if ( NULL == bitstream_in )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" );
+ }
+ if ( NULL == pcm_out )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" );
+ }
+ badFrameIndicator = 0;
+
+ return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out );
+}
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_LC3PLUS_DEC_Conceal()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_DEC_Conceal(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */
+ Word32 **pcm_out /* o : decoded samples */
+)
+{
+ uint8_t bitstream_in[LC3PLUS_MAX_BYTES];
+ int16_t badFrameIndicator;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" );
+ }
+
+ if ( NULL == pcm_out )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" );
+ }
+
+ /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */
+ badFrameIndicator = 1;
+
+ return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out );
+}
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h
new file mode 100644
index 0000000000000000000000000000000000000000..309ec4e06ba6b1b7e5e43acd3bc8e69c30721e01
--- /dev/null
+++ b/lib_isar/isar_lc3plus_dec.h
@@ -0,0 +1,136 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_LC3PLUS_DEC_H
+#define ISAR_LC3PLUS_DEC_H
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "lc3.h"
+#include "ivas_error.h"
+#include "ivas_cnst.h"
+#include "isar_lc3plus_common.h"
+
+
+typedef enum
+{
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ DEC_ACTION_DECODE_AND_DROP = 0,
+#endif
+ DEC_ACTION_DECODE_AND_USE,
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ DEC_ACTION_SKIP,
+#endif
+ DEC_ACTION_CACHE,
+ DEC_ACTION_NUM_ENUMS
+} SelectiveDecAction;
+
+
+typedef struct ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE
+{
+ /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */
+ int16_t has_skipped_a_frame;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /*! action to execute for the next frame */
+ SelectiveDecAction frame_action;
+#else
+ /*! if set to 1, decoder will skip decoding for the next frame */
+ SelectiveDecAction *frame_actions;
+#endif
+ /*! if set to 1, decoder will decode the cache before decoding any of current frames */
+ int16_t shall_decode_cached_frame;
+} ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE;
+
+typedef struct ISAR_LC3PLUS_DEC_BITSTREAM_CACHE
+{
+ uint8_t *bitstream_cache;
+ int32_t bitstream_cache_capacity;
+ int32_t bitstream_cache_size;
+} ISAR_LC3PLUS_DEC_BITSTREAM_CACHE;
+
+/* decoder wrapper */
+typedef struct ISAR_LC3PLUS_DEC_HANDLE
+{
+ LC3PLUS_Dec **handles;
+ ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states;
+ ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches;
+ uint32_t num_decs;
+ int16_t *pcm_conversion_buffer;
+ uint8_t *scratch;
+ LC3PLUS_CONFIG config;
+} * ISAR_LC3PLUS_DEC_HANDLE;
+
+ivas_error ISAR_LC3PLUS_DEC_Open(
+ const LC3PLUS_CONFIG config, /* i : decoder configuration */
+ ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */
+);
+
+ivas_error ISAR_LC3PLUS_DEC_GetDelay(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
+ int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */
+);
+
+void ISAR_LC3PLUS_DEC_Close(
+ ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */
+);
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */
+ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
+ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */
+);
+#endif
+
+ivas_error ISAR_LC3PLUS_DEC_Decode(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
+ uint8_t *bitstream_in, /* i : pointer to input bitstream */
+ const int32_t bitstream_in_size, /* i : size of bitstream_in */
+ Word32 **pcm_out /* o : decoded samples */
+);
+
+ivas_error ISAR_LC3PLUS_DEC_Conceal(
+ ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */
+ Word32 **pcm_out /* o : decoded samples */
+);
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix(
+ int16_t ***subframeChannelMatrix,
+ const uint32_t num_decs );
+
+void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix );
+#endif
+
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
+#endif /* ISAR_LC3PLUS_DEC_H */
diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c
new file mode 100644
index 0000000000000000000000000000000000000000..f6bb0284d5098656eefc25bf23614fec5056ca13
--- /dev/null
+++ b/lib_isar/isar_lc3plus_enc.c
@@ -0,0 +1,697 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "isar_lc3plus_enc.h"
+#include "isar_lc3plus_common.h"
+#include "lc3.h"
+#include "ivas_error_utils.h"
+#include "prot.h"
+#include "wmc_auto.h"
+#include "options.h"
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA;
+#endif
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config,
+ int32_t per_channel_bitrate )
+{
+ if ( config.high_res_mode_enabled )
+ {
+ switch ( config.lc3plus_frame_duration_us )
+ {
+ case 10000:
+ return min( per_channel_bitrate, 500000 );
+ case 5000:
+ return min( per_channel_bitrate, 600000 );
+ case 2500:
+ return min( per_channel_bitrate, 672000 );
+ default:
+ assert( false && "unreachable" );
+ }
+ }
+
+ switch ( config.samplerate )
+ {
+ case 48000:
+ case 32000:
+ return min( per_channel_bitrate, 320000 );
+ case 24000:
+ return min( per_channel_bitrate, 314400 );
+ case 16000:
+ return min( per_channel_bitrate, 221600 );
+ case 8000:
+ return min( per_channel_bitrate, 114400 );
+ default:
+ assert( false && "unreachable" );
+ }
+
+ assert( false && "unreachable" );
+ return -1;
+}
+#endif
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*-------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_ENC_Open()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_LC3PLUS_ENC_Open(
+ const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */
+ const UWord32 bitsPerSecond, /* i : bit rate */
+ ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */
+)
+{
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t num_lc3plus_media_times_per_ivas_frame;
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t lc3plus_num_bytes_per_frame;
+#endif
+ bool is_last_media_time, is_last_channel;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivas_error ivas_err;
+#endif
+#endif
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t bitsPerSecondPerChannel;
+#endif
+ Word32 scratch_size;
+ int32_t encoder_size;
+ LC3PLUS_Error err;
+ int32_t lfeChans[1];
+ int16_t i;
+
+ lfeChans[0] = 0;
+
+ if ( 0U == config.channels )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" );
+ }
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ bitsPerSecondPerChannel = bitsPerSecond / config.channels;
+#endif
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" );
+ }
+ if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" );
+ }
+#endif
+ encoder_size = lc3plus_enc_get_size( config.samplerate, 1 );
+ if ( 0 == encoder_size )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" );
+ }
+
+ if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ( *handle )->config = config;
+ ( *handle )->frame_type_descriptors = NULL;
+#endif
+
+ ( *handle )->pcm_conversion_buffer = NULL;
+ ( *handle )->num_encs = 0;
+ if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" );
+ }
+
+ for ( i = 0; i < config.channels; ++i )
+ {
+ ( *handle )->handles[i] = NULL;
+ }
+ ( *handle )->num_encs = config.channels;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us;
+ ( *handle )->fdl_request = s_fdl_request;
+ ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame;
+ ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) );
+ if ( NULL == ( *handle )->frame_type_descriptors )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" );
+ }
+#endif
+
+ for ( int32_t iCh = 0; iCh < config.channels; iCh++ )
+ {
+ if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans );
+#else
+ err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans );
+#endif
+ if ( err != LC3PLUS_OK )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" );
+ }
+
+ err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 );
+ if ( err != LC3PLUS_OK )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" );
+ }
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel );
+ if ( err != LC3PLUS_OK )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" );
+ }
+#endif
+ }
+
+ if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" );
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ( *handle )->config = config;
+#endif
+ ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 );
+ if ( NULL == ( *handle )->pcm_conversion_buffer )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /* update FDI fields */
+ for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime )
+ {
+ for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc )
+ {
+ int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */
+#else
+ lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] );
+ if ( lc3plus_num_bytes_per_frame <= 0 )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" );
+ }
+ ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame;
+#endif
+ if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" );
+ }
+ if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" );
+ }
+ ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY;
+ ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL;
+
+ /* The FTDs in the ToC are included in the following order:
+ * 1) First the FTD for the first channel of the first FDB (oldest frame)
+ * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order
+ * 3) Then the FTD for the first channel of the second FDB
+ * 4) Then the FTDs for the remaining channels for the second FDB
+ * 5) Etc. to the last FDB */
+ is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime;
+ is_last_channel = ( *handle )->num_encs - 1 == iEnc;
+ if ( is_last_media_time && is_last_channel )
+ {
+ ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL;
+ }
+ else if ( !is_last_media_time && is_last_channel )
+ {
+ ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME;
+ }
+ else
+ {
+ ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL;
+ }
+ }
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond );
+ if ( ivas_err != IVAS_ERR_OK )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return ivas_err;
+ }
+#endif
+#endif
+ scratch_size = lc3plus_enc_get_scratch_size( ( *handle )->handles[0] );
+ ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size );
+ IF( NULL == ( *handle )->scratch )
+ {
+ ISAR_LC3PLUS_ENC_Close( handle );
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper scratch\n" );
+ }
+
+ return IVAS_ERR_OK;
+}
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*-------------------------------------------------------------------*
+ * Function IVAS_LC3PLUS_ENC_SetBitrate()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error IVAS_LC3PLUS_ENC_SetBitrate(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */
+ const uint32_t bitsPerSecond /* i : new target bit rate */
+)
+{
+ int32_t numLc3plusMediaTimesPerIvasFrame;
+ int32_t lc3plus_num_bytes_per_frame;
+ int32_t availableOctetsPerIsarFrame;
+ int32_t actualOctetsPerFrame;
+ LC3PLUS_Error err;
+ int32_t iFtd;
+ int32_t fdrLength;
+ int32_t lc3plusPacketRate;
+ int32_t numSubframes;
+ int32_t minPayloadOverhead;
+ int32_t targetLc3PlusBitratePerChannel;
+ int32_t targetLc3PlusOctetCount;
+ int32_t lc3plusFdlLength;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
+ }
+
+ availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8;
+ lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us;
+ numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+ numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels;
+
+ /* subtract minimum required payload bytes & calculate a first per-channel target bit rate */
+ if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" );
+ }
+ minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE );
+ targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( targetLc3PlusBitratePerChannel <= 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" );
+ }
+#endif
+ targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel );
+ targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate;
+ /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */
+ if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" );
+ }
+ if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH )
+ {
+ /* reduce bitrate to allow for the required fdl field */
+ targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate;
+ }
+
+ for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ )
+ {
+ err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel );
+ if ( err != LC3PLUS_OK )
+ {
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" );
+ }
+ }
+
+ // update FTD settings after bitrate change
+ for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime )
+ {
+ for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc )
+ {
+ iFtd = iEnc + iMediaTime * handle->num_encs;
+ lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
+ if ( lc3plus_num_bytes_per_frame <= 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" );
+ }
+ handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame;
+ }
+ }
+
+ // TODO: remove sanity checks?
+ if ( ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "ISAR_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" );
+ }
+ if ( actualOctetsPerFrame > availableOctetsPerIsarFrame )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" );
+ }
+ return IVAS_ERR_OK;
+}
+#endif
+
+
+/*-------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_ENC_GetDelay()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_ENC_GetDelay(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ int32_t *delayInSamples /* o : encoder delay in number of samples per channel */
+)
+{
+ int32_t tmpDelayInSamples;
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
+ }
+ if ( NULL == delayInSamples )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" );
+ }
+
+ *delayInSamples = 0;
+ /* sanity check whether all encoders are actually configured identically */
+ for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ )
+ {
+ if ( NULL == handle->handles[iEnc] )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" );
+ }
+
+ tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] );
+ if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" );
+ }
+ *delayInSamples = tmpDelayInSamples;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ Word32 *bsSize /* o : size of each bitstream frame in bytes */
+)
+{
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ LC3PLUS_RTP_ERR rtp_err;
+ int32_t num_lc3plus_media_times_per_ivas_frame;
+ int32_t iMediaTime;
+ int32_t ftd_frame_data_length_size, lc3plus_frame_data_length;
+ int32_t ftd_index;
+#else
+ int32_t bitstreamSizeMultiplier;
+#endif
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
+ }
+ if ( NULL == bsSize )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( 0 == handle->config.lc3plus_frame_duration_us )
+ {
+ return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" );
+ }
+ if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
+ }
+
+ num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+#endif
+ *bsSize = 0;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t fdl_request_length;
+ rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request );
+ if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" );
+ }
+ *bsSize += fdl_request_length;
+#endif
+ for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ )
+ {
+ if ( NULL == handle->handles[iEnc] )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
+ for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime )
+ {
+ ftd_index = iEnc + iMediaTime * handle->num_encs;
+ if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" );
+ }
+ rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length );
+ if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" );
+ }
+ *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL;
+ *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length;
+ *bsSize += ftd_frame_data_length_size;
+ }
+ }
+#else
+ *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] );
+ }
+
+ if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
+ }
+ bitstreamSizeMultiplier = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+
+ *bsSize *= bitstreamSizeMultiplier;
+#endif
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_ENC_Close()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ISAR_LC3PLUS_ENC_Close(
+ ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
+)
+{
+ if ( NULL == handle || NULL == *handle )
+ {
+ return;
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( NULL != ( *handle )->frame_type_descriptors )
+ {
+ free( ( *handle )->frame_type_descriptors );
+ }
+#endif
+ for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ )
+ {
+ if ( NULL != ( *handle )->handles[iEnc] )
+ {
+ free( ( *handle )->handles[iEnc] );
+ }
+ }
+ if ( NULL != ( *handle )->pcm_conversion_buffer )
+ {
+ free( ( *handle )->pcm_conversion_buffer );
+ }
+
+ if ( NULL != ( *handle )->scratch )
+ {
+ free( ( *handle )->scratch );
+ }
+
+ free( ( *handle )->handles );
+ free( *handle );
+
+ *handle = NULL;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Function ISAR_LC3PLUS_ENC_Encode()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_LC3PLUS_ENC_Encode(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ Word32 **pcm_in, /* i : pointer input samples */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ void *bitstream_out, /* o : pointer to bitstream frame */
+ const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */
+#else
+ void *bitstream_out /* o : pointer to bitstream frame */
+#endif
+ Word16 q_in[16] )
+{
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t ftdIndex;
+ LC3PLUS_RTP_ERR rtpErr;
+ uint32_t num_media_times;
+#else
+ uint32_t lc3framesPerIvasFrame;
+ uint8_t *bitstream_out_iter = bitstream_out;
+#endif
+ uint32_t numSamplesPerLC3plusChannel;
+ int32_t ivasSampleIndex;
+ int32_t num_bytes = 0;
+ LC3PLUS_Error err;
+
+ push_wmops( "ISAR_LC3PLUS_ENC_Encode" );
+
+ if ( NULL == handle )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" );
+ }
+ if ( NULL == pcm_in )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" );
+ }
+ if ( NULL == bitstream_out )
+ {
+ return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" );
+ }
+
+ if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 )
+ {
+ return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+ numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times;
+
+ size_t actual_size;
+ rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds );
+ if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" );
+ }
+#else
+ lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us;
+
+ numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame;
+#endif
+ for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ )
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ )
+#else
+ for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ )
+#endif
+ {
+ for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ )
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel;
+#else
+ ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel;
+#endif
+ handle->pcm_conversion_buffer[iSampleInt16] = (Word16) max( INT16_MIN, min( L_shr( pcm_in[iEnc][ivasSampleIndex], q_in[iEnc] ), INT16_MAX ) );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ftdIndex = iMediaTime * handle->num_encs + iEnc;
+#endif
+ num_bytes = 0;
+ push_wmops( "lc3plus_enc16" );
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, handle->scratch );
+#else
+ err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL );
+#endif
+ pop_wmops();
+ if ( err != LC3PLUS_OK )
+ {
+ return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" );
+ }
+ if ( 0 == num_bytes )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" );
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" );
+ }
+#else
+
+ bitstream_out_iter += num_bytes;
+#endif
+ }
+ }
+
+ pop_wmops();
+
+ return IVAS_ERR_OK;
+}
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2bc10bfc99b16524d42721bc4155ea240d916cd
--- /dev/null
+++ b/lib_isar/isar_lc3plus_enc.h
@@ -0,0 +1,104 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_LC3PLUS_ENC_H
+#define ISAR_LC3PLUS_ENC_H
+
+#include
+#include "ivas_error.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "lc3.h"
+#include "isar_lc3plus_common.h"
+#include "typedef.h"
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+#include "isar_lc3plus_payload.h"
+#endif
+
+/* encoder wrapper */
+typedef struct ISAR_LC3PLUS_ENC_HANDLE
+{
+ LC3PLUS_CONFIG config;
+ LC3PLUS_Enc **handles;
+ uint32_t num_encs;
+ int16_t *pcm_conversion_buffer;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ LC3PLUS_RTP_FTD *frame_type_descriptors;
+ int32_t num_ftds;
+ LC3PLUS_RTP_FDL fdl_request;
+#endif
+ uint8_t *scratch;
+} * ISAR_LC3PLUS_ENC_HANDLE;
+
+ivas_error ISAR_LC3PLUS_ENC_Open(
+ const LC3PLUS_CONFIG config, /* i : encoder configuration */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const uint32_t initialBitsPerSecond, /* i : initial target bit rate */
+#else
+ const uint32_t bitsPerSecond, /* i : bit rate */
+#endif
+ ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */
+);
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ivas_error IVAS_LC3PLUS_ENC_SetBitrate(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */
+ const uint32_t bitsPerSecond /* i : new target bit rate */
+);
+#endif
+
+ivas_error ISAR_LC3PLUS_ENC_GetDelay(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */
+);
+
+ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ int32_t *bsSize /* o : size of next bitstream frame in bytes */
+);
+
+void ISAR_LC3PLUS_ENC_Close(
+ ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */
+);
+
+ivas_error ISAR_LC3PLUS_ENC_Encode(
+ ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */
+ Word32 **pcm_in, /* i : pointer input samples */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ void *bitstream_out, /* o : pointer to bitstream frame */
+ const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */
+#else
+ void *bitstream_out /* o : pointer to bitstream frame */
+#endif
+ Word16 q_in[16] );
+#endif
+
+#endif /* ISAR_LC3PLUS_ENC_H */
diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa47189caef9196c8e02dea0f79e031fbfc4e26b
--- /dev/null
+++ b/lib_isar/isar_lc3plus_payload.c
@@ -0,0 +1,823 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include
+#include
+#include "isar_lc3plus_payload.h"
+#include "options.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi )
+{
+ if ( NULL == frame_duration_us )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ switch ( fdi )
+ {
+ case LC3PLUS_RTP_FTD_FDI_2500_US:
+ *frame_duration_us = 2500;
+ break;
+ case LC3PLUS_RTP_FTD_FDI_5000_US:
+ *frame_duration_us = 5000;
+ break;
+ case LC3PLUS_RTP_FTD_FDI_10000_US:
+ *frame_duration_us = 10000;
+ break;
+ case LC3PLUS_RTP_FTD_FDI_RESERVED:
+ default:
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr )
+{
+ if ( NULL == sample_rate_hz )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ switch ( bwr )
+ {
+ case LC3PLUS_RTP_FTD_BWR_NB:
+ *sample_rate_hz = 8000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_WB:
+ *sample_rate_hz = 16000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_SSWB:
+ *sample_rate_hz = 24000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_SWB:
+ *sample_rate_hz = 32000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FBCD:
+ *sample_rate_hz = 44100;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FB:
+ *sample_rate_hz = 48000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FBHR:
+ *sample_rate_hz = 48000;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_UBHR:
+ *sample_rate_hz = 96000;
+ break;
+ default:
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr )
+{
+ if ( NULL == high_resolution_flag )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ switch ( bwr )
+ {
+ case LC3PLUS_RTP_FTD_BWR_NB:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_WB:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_SSWB:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_SWB:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FBCD:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FB:
+ *high_resolution_flag = 0;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_FBHR:
+ *high_resolution_flag = 1;
+ break;
+ case LC3PLUS_RTP_FTD_BWR_UBHR:
+ *high_resolution_flag = 1;
+ break;
+ default:
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue )
+{
+ if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID )
+ {
+ *length = 1;
+ }
+ else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX )
+ {
+ *length = 1;
+ }
+ else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX )
+ {
+ *length = 2;
+ }
+ else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
+ {
+ *length = 3;
+ }
+ else
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst )
+{
+ int32_t frame_data_length_size;
+ LC3PLUS_RTP_ERR err;
+
+ if ( NULL == dst )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+
+ err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue );
+ if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return err;
+ }
+ if ( 1 == frame_data_length_size )
+ {
+ *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ }
+ else if ( 2 == frame_data_length_size )
+ {
+ const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ }
+ else if ( 3 == frame_data_length_size )
+ {
+ const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE );
+ *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl )
+{
+ if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
+ {
+ return fdl;
+ }
+ return 0;
+}
+
+static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl )
+{
+ if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD )
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request )
+{
+ /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */
+ if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) )
+ {
+ return true;
+ }
+ return false;
+}
+
+static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity )
+{
+ int32_t frame_data_length_size;
+ LC3PLUS_RTP_ERR err;
+ if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+
+ if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) )
+ {
+ *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ }
+ else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src )
+ {
+ *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
+ }
+ else if ( remaining_capacity > 0 )
+ {
+ *frame_data_length_value = *src << 0;
+ }
+ else
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+
+ /* sanity check */
+ err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value );
+ if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return err;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity )
+{
+ int32_t frame_data_block_size;
+ LC3PLUS_RTP_FDL fdl;
+ LC3PLUS_RTP_ERR err;
+ if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+
+ *num_bytes_read = 0;
+ receiver_ftd->fc = 0;
+ receiver_ftd->fdi = 0;
+ receiver_ftd->bwr = 0;
+ receiver_ftd->h = 0;
+ receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK;
+ receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK );
+ receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK );
+ receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK );
+ p_read++;
+ *num_bytes_read = 1;
+
+ err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ frame_data_block_size = s_get_size_from_fdl( fdl );
+
+ receiver_ftd->frame_data_length = frame_data_block_size;
+ int32_t length_field_size;
+ err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ *num_bytes_read += length_field_size;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize(
+ uint8_t *serialized_buffer,
+ const size_t serialized_buffer_capacity,
+ size_t *packed_buffer_actual_size,
+ const LC3PLUS_RTP_FDL fdl_request,
+ LC3PLUS_RTP_FTD *sender_ftds,
+ const size_t sender_ftds_num )
+{
+ LC3PLUS_RTP_ERR err;
+ uint8_t *p_write = serialized_buffer;
+ uint32_t i;
+ int32_t bytes_written = 0;
+ int32_t lc3plus_frame_size_sum;
+ uint8_t *p_frame_data;
+ int32_t fdl_request_length;
+
+ if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+
+ *packed_buffer_actual_size = 0;
+ err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( !s_fdl_value_is_valid_request( fdl_request ) )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
+ }
+ if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ err = s_frame_data_length_pack( fdl_request, p_write );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ bytes_written += fdl_request_length;
+ p_write += bytes_written;
+
+ for ( i = 0; i < sender_ftds_num; ++i )
+ {
+ /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
+ if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
+ if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ *p_write = 0x00;
+ *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc;
+ *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi;
+ *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr;
+ *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h;
+ p_write++;
+ bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL;
+
+ int32_t fdl_length;
+ err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ p_write += fdl_length;
+ bytes_written += fdl_length;
+ }
+
+ lc3plus_frame_size_sum = 0;
+ p_frame_data = serialized_buffer + bytes_written;
+ for ( i = 0; i < sender_ftds_num; ++i )
+ {
+ sender_ftds[i].frame_data = p_frame_data;
+ p_frame_data += sender_ftds[i].frame_data_length;
+ lc3plus_frame_size_sum += sender_ftds[i].frame_data_length;
+ }
+ *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum;
+ assert( *packed_buffer_actual_size <= serialized_buffer_capacity );
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+static LC3PLUS_RTP_ERR s_ftds_parse(
+ LC3PLUS_RTP_FTD *receiver_ftds,
+ const int32_t receiver_ftds_num_max,
+ int16_t *receiver_ftds_num,
+ uint8_t *serialized_buffer,
+ const size_t serialized_buffer_size )
+{
+ int32_t diff;
+ uint8_t *p_read;
+ uint32_t ftds_offset_sum = 0;
+ int16_t i;
+ LC3PLUS_RTP_ERR error;
+ int32_t frame_offset_counter;
+ int32_t size;
+
+ p_read = serialized_buffer;
+ if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ if ( 0 == serialized_buffer_size )
+ {
+ return LC3PLUS_RTP_ERR_EMPTY_TOC;
+ }
+ if ( receiver_ftds_num_max <= 0 )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ {
+ int32_t num_bytes_read_sum = 0;
+ const int32_t min_num_bytes_per_ftd = 2;
+ int16_t receiver_ftds_index = 0;
+ bool another_ftd = true;
+ int32_t num_bytes_read_per_ftd;
+
+ while ( another_ftd )
+ {
+ if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ num_bytes_read_per_ftd = 0;
+ error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != error )
+ {
+ return error;
+ }
+ p_read += num_bytes_read_per_ftd;
+ num_bytes_read_sum += num_bytes_read_per_ftd;
+
+ if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
+ }
+ else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL )
+ {
+ another_ftd = false;
+ }
+
+ if ( another_ftd )
+ {
+ if ( receiver_ftds_index >= receiver_ftds_num_max )
+ {
+ return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED;
+ }
+ ( receiver_ftds_index )++;
+ }
+ }
+ *receiver_ftds_num = receiver_ftds_index + 1;
+ }
+
+ /* set frame-data pointers into serialized_buffer */
+ for ( i = 0; i < *receiver_ftds_num; ++i )
+ {
+ error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length );
+ if ( error != LC3PLUS_RTP_ERR_NO_ERROR )
+ {
+ return error;
+ }
+ ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size;
+ }
+
+ frame_offset_counter = 0;
+ for ( i = 0; i < *receiver_ftds_num; ++i )
+ {
+ if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) )
+ {
+ receiver_ftds[i].frame_data = NULL;
+ }
+ else
+ {
+ receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter;
+ frame_offset_counter += receiver_ftds[i].frame_data_length;
+ }
+ }
+
+ if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size )
+ {
+ /* parsed content & size n bytes of input buffer do not line up */
+ /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */
+ diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter );
+ if ( diff < 0 )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
+ }
+ /* verify that all bytes are zero */
+ p_read += frame_offset_counter;
+ for ( i = 0; i < diff; ++i )
+ {
+ if ( *p_read != 0 )
+ {
+ /* non-zero byte in padding region */
+ return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES;
+ }
+ p_read++;
+ }
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize(
+ LC3PLUS_RTP_PAYLOAD *payload,
+ uint8_t *serialized_buffer,
+ const size_t serialized_buffer_size )
+{
+ int32_t new_frame_duration_us;
+ int32_t new_sampling_rate_hz;
+ int16_t new_high_resolution_flag;
+ int16_t i = 0;
+ int16_t channel_id = 0;
+ int16_t media_time_id = 0;
+ const int16_t invalid_value = -1;
+ int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS];
+ int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES];
+ LC3PLUS_RTP_ERR err;
+
+ if ( NULL == payload || NULL == serialized_buffer )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ if ( 0 == serialized_buffer_size )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+
+ for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id )
+ {
+ channels_per_media_time[media_time_id] = invalid_value;
+ }
+ media_time_id = 0;
+ for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id )
+ {
+ media_times_per_channel[channel_id] = invalid_value;
+ }
+ channel_id = 0;
+
+ err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ int32_t fdl_request_length;
+ err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( !s_fdl_value_is_valid_request( payload->fdl_request ) )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
+ }
+
+ err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( 0 == payload->num_ftds )
+ {
+ return LC3PLUS_RTP_ERR_GENERIC_ERROR;
+ }
+ /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */
+
+ /* initialize on the first FTD, use this as reference */
+ err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ payload->num_channels = 0;
+ payload->num_media_times = 0;
+ for ( i = 0; i < payload->num_ftds; ++i )
+ {
+ if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY )
+ {
+ /* not implemented */
+ return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
+ }
+
+ err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( payload->frame_duration_us != new_frame_duration_us )
+ {
+ /* mixed frame durations not supported */
+ return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
+ }
+
+ err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( payload->sampling_rate_hz != new_sampling_rate_hz )
+ {
+ /* mixed sampling frequencies not supported */
+ return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
+ }
+
+
+ err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr );
+ if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
+ {
+ return err;
+ }
+ if ( payload->high_resolution_enabled != new_high_resolution_flag )
+ {
+ /* mixed high resolution mode not supported */
+ return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
+ }
+
+ switch ( payload->ftds[i].fc )
+ {
+ case LC3PLUS_RTP_FTD_FC_LAST_OVERALL:
+ channels_per_media_time[media_time_id]++;
+ media_times_per_channel[channel_id]++;
+ channel_id = 0;
+ media_time_id = 0;
+ break;
+ case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL:
+ media_times_per_channel[channel_id]++;
+ channels_per_media_time[media_time_id]++;
+ channel_id++;
+ break;
+ case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME:
+ media_times_per_channel[channel_id]++;
+ channels_per_media_time[media_time_id]++;
+ channel_id = 0;
+ media_time_id++;
+ break;
+ case LC3PLUS_RTP_FTD_FC_RESERVED:
+ default:
+ return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
+ }
+ }
+
+ {
+ int32_t valid_num_media_times_per_channel;
+ int32_t iCh;
+ /* check whether all channels exist for each media time */
+ if ( media_times_per_channel[0] == invalid_value )
+ {
+ return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
+ }
+ valid_num_media_times_per_channel = media_times_per_channel[0];
+ for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh )
+ {
+ if ( media_times_per_channel[iCh] == invalid_value )
+ {
+ break;
+ }
+ if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] )
+ {
+ return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
+ }
+ }
+ }
+ {
+ /* whether all media times exist for each channel */
+ int32_t iMediaTime;
+ int32_t valid_num_channels_per_media_time;
+ if ( channels_per_media_time[0] == invalid_value )
+ {
+ return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
+ }
+ valid_num_channels_per_media_time = channels_per_media_time[0];
+ for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime )
+ {
+ if ( channels_per_media_time[iMediaTime] == invalid_value )
+ {
+ break;
+ }
+ if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] )
+ {
+ return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
+ }
+ }
+ }
+
+ /* convert zero-index to count */
+ payload->num_channels = channels_per_media_time[0] + 1;
+ payload->num_media_times = media_times_per_channel[0] + 1;
+
+ /* verify that all media times have the same number of channels, partial packets are not supported */
+ if ( payload->num_ftds != payload->num_channels * payload->num_media_times )
+ {
+ return LC3PLUS_RTP_ERR_GENERIC_ERROR;
+ }
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+}
+
+LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled )
+{
+ if ( NULL == bwr )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ switch ( sampling_rate )
+ {
+ case 8000:
+ if ( high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_NB;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 16000:
+ if ( high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_WB;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 24000:
+ if ( high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_SSWB;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 32000:
+ if ( high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_SWB;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 44100:
+ if ( high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_FBCD;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 48000:
+ if ( 0 == high_res_enabled )
+ {
+ *bwr = LC3PLUS_RTP_FTD_BWR_FB;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ }
+ else
+ {
+ *bwr = LC3PLUS_RTP_FTD_BWR_FBHR;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ }
+ case 96000:
+ if ( 0 == high_res_enabled )
+ {
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+ }
+ *bwr = LC3PLUS_RTP_FTD_BWR_UBHR;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ default:
+ break;
+ }
+
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+}
+
+LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us )
+{
+ if ( NULL == fdi )
+ {
+ return LC3PLUS_RTP_ERR_NULL_PTR;
+ }
+ switch ( frame_duration_us )
+ {
+ case 2500:
+ *fdi = LC3PLUS_RTP_FTD_FDI_2500_US;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 5000:
+ *fdi = LC3PLUS_RTP_FTD_FDI_5000_US;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ case 10000:
+ *fdi = LC3PLUS_RTP_FTD_FDI_10000_US;
+ return LC3PLUS_RTP_ERR_NO_ERROR;
+ default:
+ break;
+ }
+
+ return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
+}
+
+#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h
new file mode 100644
index 0000000000000000000000000000000000000000..3af6757fadf93122ac7a5e8d1dde77a524acc0e1
--- /dev/null
+++ b/lib_isar/isar_lc3plus_payload.h
@@ -0,0 +1,216 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_LC3PLUS_PAYLOAD_H
+#define ISAR_LC3PLUS_PAYLOAD_H
+
+#include
+#include
+#include "lc3.h"
+#include "options.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+
+/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format
+ * for LC3plus as specified in ETSI TS 103 634. */
+
+typedef enum LC3PLUS_RTP_ERR
+{
+ LC3PLUS_RTP_ERR_NO_ERROR,
+ LC3PLUS_RTP_ERR_NULL_PTR,
+ LC3PLUS_RTP_ERR_INVALID_PARAMETERS,
+ LC3PLUS_RTP_ERR_EMPTY_TOC,
+ LC3PLUS_RTP_ERR_NOT_IMPLEMENTED,
+ LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION,
+ LC3PLUS_RTP_ERR_INVALID_BITSTREAM,
+ LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE,
+ LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED,
+ LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST,
+ LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES,
+ LC3PLUS_RTP_ERR_GENERIC_ERROR
+} LC3PLUS_RTP_ERR;
+
+/*
+ * The content of the FTD is shown in Figure B.6.
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/* FC (2 bits):
+ * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC
+ * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments
+ * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent
+ * FTD (if available). */
+typedef enum LC3PLUS_RTP_FTD_FC
+{
+ LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */
+ LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */
+ LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */
+ LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */
+} LC3PLUS_RTP_FTD_FC;
+#define LC3PLUS_RTP_FTD_FC_MASK 0x03
+
+/* FDI (2 bits):
+ * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given
+ * payload type during the session. The FDI also dictates the TSI, needed for deriving the media
+ * time in case of more than one frame in the payload. */
+typedef enum LC3PLUS_RTP_FTD_FDI
+{
+ LC3PLUS_RTP_FTD_FDI_2500_US = 0x00,
+ LC3PLUS_RTP_FTD_FDI_5000_US = 0x04,
+ LC3PLUS_RTP_FTD_FDI_10000_US = 0x08,
+ LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C,
+} LC3PLUS_RTP_FTD_FDI;
+#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C
+LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us );
+
+/* BWR (3 bits):
+ * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and
+ * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is
+ * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */
+typedef enum LC3PLUS_RTP_FTD_BWR
+{
+ LC3PLUS_RTP_FTD_BWR_NB = 0x00,
+ LC3PLUS_RTP_FTD_BWR_WB = 0x10,
+ LC3PLUS_RTP_FTD_BWR_SSWB = 0x20,
+ LC3PLUS_RTP_FTD_BWR_SWB = 0x30,
+ LC3PLUS_RTP_FTD_BWR_FBCD = 0x40,
+ LC3PLUS_RTP_FTD_BWR_FB = 0x50,
+ LC3PLUS_RTP_FTD_BWR_FBHR = 0x60,
+ LC3PLUS_RTP_FTD_BWR_UBHR = 0x70,
+} LC3PLUS_RTP_FTD_BWR;
+#define LC3PLUS_RTP_FTD_BWR_MASK 0x70
+LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled );
+
+/* H (1 bit):
+ * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame
+ * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */
+typedef enum LC3PLUS_RTP_FTD_H
+{
+ LC3PLUS_RTP_FTD_H_PRIMARY = 0x00,
+ LC3PLUS_RTP_FTD_H_SECONDARY = 0x80,
+} LC3PLUS_RTP_FTD_H;
+#define LC3PLUS_RTP_FTD_H_MASK 0x80
+
+typedef enum LC3PLUS_RTP_FDL
+{
+ LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0,
+ LC3PLUS_RTP_FDL_SPEECH_BAD = 1,
+ LC3PLUS_RTP_FDL_SPEECH_SID = 2,
+ LC3PLUS_RTP_FDL_RESERVED_MIN = 3,
+ LC3PLUS_RTP_FDL_RESERVED_MAX = 19,
+ LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20,
+ LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254,
+ LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255,
+ LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509,
+ LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510,
+ LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765
+} LC3PLUS_RTP_FDL;
+/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */
+#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF
+
+typedef struct LC3PLUS_RTP_FTD
+{
+ LC3PLUS_RTP_FTD_FC fc;
+ LC3PLUS_RTP_FTD_FDI fdi;
+ LC3PLUS_RTP_FTD_BWR bwr;
+ LC3PLUS_RTP_FTD_H h;
+ uint8_t *frame_data;
+ LC3PLUS_RTP_FDL frame_data_length;
+} LC3PLUS_RTP_FTD;
+#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1
+#define LC3PLUS_RTP_FDL_MIN_LENGTH 1
+#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH )
+
+/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer
+ * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to
+ * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes
+ * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity)
+ * @param[in] fdl_request frame data length request
+ * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in
+ * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call)
+ * @param[in] sender_ftds_num number of sender_ftds
+ * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
+LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize(
+ uint8_t *serialized_buffer,
+ const size_t serialized_buffer_capacity,
+ size_t *packed_buffer_actual_size,
+ const LC3PLUS_RTP_FDL fdl_request,
+ LC3PLUS_RTP_FTD *sender_ftds,
+ const size_t sender_ftds_num );
+
+/*! Get size of the frame data length field for a certain frame data length value in bytes.
+ * @param[out] length size of the frame data length field in bytes [1,2,3]
+ * @param[in] frameDataLengthValue frame data length value
+ * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
+LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue );
+
+#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16
+#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */
+#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES
+
+typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG
+{
+ /* frame duration in us shared among all FTDs */
+ int32_t frame_duration_us;
+ /* high resolution flag shared among all FTDs */
+ int16_t high_resolution_enabled;
+ /* sampling frequency shared among all FTDs */
+ int32_t sampling_rate_hz;
+ /* number of individual channels in the payload */
+ int16_t num_channels;
+ /* number of individual media times in the payload */
+ int16_t num_media_times;
+ /* frame data length request */
+ LC3PLUS_RTP_FDL fdl_request;
+ /* FTD data with pointer to raw frame data */
+ LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS];
+ /* actual number of ftds */
+ int16_t num_ftds;
+} LC3PLUS_RTP_PAYLOAD;
+
+/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct
+ * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer.
+ * @param serialized_buffer pointer to the start of the serialized input buffer
+ * @param serialized_buffer_size size of the serialized input buffer in bytes
+ * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */
+LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize(
+ LC3PLUS_RTP_PAYLOAD *payload,
+ uint8_t *serialized_buffer,
+ const size_t serialized_buffer_size );
+
+#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */
+#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */
+#endif /* ISAR_LC3PLUS_PAYLOAD_H */
diff --git a/lib_isar/isar_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..c067ad0647f0f66ea888c9f537420b9924456cd3
--- /dev/null
+++ b/lib_isar/isar_lcld_decoder.c
@@ -0,0 +1,1993 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_lcld_prot.h"
+#include "isar_lcld_rom_tables.h"
+#include "prot.h"
+#include
+#include "isar_prot.h"
+#include "wmc_auto.h"
+#include "basop_util.h"
+#include "prot_fx2.h"
+// #define DEBUG_WRITE
+#include "debug.h"
+#include "enh64.h"
+
+/*------------------------------------------------------------------------------------------*
+ * Local constants
+ *------------------------------------------------------------------------------------------*/
+
+#define HUFF_READ_SIZE ( 4 )
+
+/*------------------------------------------------------------------------------------------*
+ * Local structures
+ *------------------------------------------------------------------------------------------*/
+
+typedef struct TableNode
+{
+ struct TableNode **ppoNextTable;
+ struct TableNode *poOrderedNext;
+
+ Word32 *piCodeIndex;
+ Word32 *piDifference;
+ Word32 *piLength;
+} TableNode;
+
+typedef struct TableList
+{
+ TableNode *poOrderedTop;
+ TableNode *poOrderedBottom;
+
+} TableList;
+
+struct LCLD_DECODER
+{
+ Word32 iSampleRate;
+ Word32 iChannels;
+ Word32 iNumBlocks;
+
+ Word32 iNumBands;
+ const Word32 *piBandwidths;
+
+ Word32 iMSMode;
+ Word32 *piMSFlags;
+ TableList *ptable_list;
+ UWord32 ( *c_apauiHuffDecTable_RAM[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE];
+ UWord32 num_decode_table[2 * ALLOC_TABLE_SIZE];
+ Word32 piMSPredCoefs[MAX_BANDS];
+ Word32 piLRPhaseDiffs[MAX_BANDS];
+ Word32 iCommonGrouping;
+ Word32 *piNumGroups;
+ Word32 **ppiGroupLengths;
+
+ Word32 ***pppiRMSEnvelope;
+ Word32 ***pppiSMR;
+ Word32 ***pppiExcitation;
+ Word32 ***pppiAlloc;
+
+ Word32 iAllocOffset;
+ Word32 iRealOnlyOut;
+
+ Word32 ***pppiLCLDSignReal;
+ Word32 ***pppiLCLDSignImag;
+ Word32 ***pppiQLCLDReal;
+ Word32 ***pppiQLCLDImag;
+
+ PredictionDecoder *psPredictionDecoder;
+
+
+ NoiseGen *psNoiseGen;
+};
+
+static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables );
+static TableNode *CreateTableList( Word32 iReadLength );
+static void DeleteTableList( TableList *ptable_list, Word32 iTables );
+static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated );
+static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables );
+static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated );
+
+static TableNode *CreateTableList( Word32 iReadLength )
+{
+ Word32 n;
+ Word32 iMaxTables;
+ TableNode *ptable_top;
+ iMaxTables = L_shl( 1, (Word16) iReadLength );
+ ptable_top = (TableNode *) malloc( sizeof( TableNode ) );
+ ptable_top->ppoNextTable =
+ (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) );
+ ptable_top->piCodeIndex = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) );
+ ptable_top->piDifference = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) );
+ ptable_top->piLength = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) );
+ FOR( n = 0; n < iMaxTables; n++ )
+ {
+ ptable_top->ppoNextTable[n] = NULL;
+ ptable_top->piCodeIndex[n] = 0xffff;
+ move32();
+ ptable_top->piDifference[n] = 0;
+ move32();
+ ptable_top->piLength[n] = 0;
+ move32();
+ }
+
+ return ptable_top;
+}
+
+static void DeleteTableList( TableList *ptable_list, Word32 iTables )
+{
+
+ TableNode *node;
+ node = ptable_list->poOrderedTop;
+
+ WHILE( ( iTables ) )
+ {
+
+ TableNode *node1 = node;
+ node = node1->poOrderedNext;
+ IF( node1->piCodeIndex != NULL )
+ {
+ free( node1->piCodeIndex );
+ }
+ IF( node1->piLength != NULL )
+ {
+ free( node1->piLength );
+ }
+ IF( node1->piDifference != NULL )
+ {
+ free( node1->piDifference );
+ }
+ IF( node1->ppoNextTable != NULL )
+ {
+ free( node1->ppoNextTable );
+ }
+ IF( node1 != NULL )
+ {
+ free( node1 );
+ }
+ iTables--;
+ }
+ IF( ptable_list != NULL )
+ {
+ free( ptable_list );
+ }
+}
+
+static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated )
+{
+ TableNode *poNextNode;
+
+ IF( poParent->ppoNextTable[iIndex] == NULL )
+ {
+ poNextNode = CreateTableList( iReadLength );
+ poParent->ppoNextTable[iIndex] = poNextNode;
+ poParent->piDifference[iIndex] = *iTablesCreated; /* this is a link to the next table rather than the difference */
+ move32();
+ table_list->poOrderedBottom->poOrderedNext = poNextNode;
+ table_list->poOrderedBottom = poNextNode;
+
+ ( *iTablesCreated )++;
+ }
+ ELSE
+ {
+ poNextNode = poParent->ppoNextTable[iIndex];
+ }
+
+ return poNextNode;
+}
+
+static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated )
+{
+
+ Word32 iMaxTables;
+ Word32 j;
+ TableNode *poNode;
+
+ iMaxTables = L_shl( 1, (Word16) iReadLength );
+ psLCLDDecoder->c_apauiHuffDecTable_RAM[n] =
+ malloc( iTablesCreated * iMaxTables * sizeof( UWord32 * ) );
+
+ poNode = ptable_list->poOrderedTop;
+ FOR( j = 0; j < iTablesCreated; j++ )
+ {
+ Word32 k;
+ IF( poNode != NULL )
+ {
+ FOR( k = 0; k < iMaxTables; k++ )
+ {
+ UWord32 uiCode;
+ uiCode = poNode->piDifference[k];
+ move32();
+ uiCode = (UWord32) L_shl( (Word32) uiCode, 16 );
+ uiCode = (UWord32) L_or( (Word32) uiCode, poNode->piCodeIndex[k] );
+ psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode;
+ move32();
+ }
+ }
+ poNode = poNode->poOrderedNext;
+ }
+}
+
+static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables )
+{
+ Word32 iDifference;
+ Word32 iMask;
+ Word32 iCurrentLength;
+ Word32 iIndex;
+ Word32 iCodeLow;
+ Word32 iCodeHigh;
+
+ TableNode *poNode;
+ poNode = ptable_list->poOrderedTop;
+ iMask = L_sub( L_shl( 1, (Word16) iReadLength ), 1 );
+ iCurrentLength = iLength;
+ move32();
+ WHILE( GT_32( iCurrentLength, iReadLength ) )
+ {
+ iDifference = L_sub( iCurrentLength, iReadLength );
+ iIndex = L_shr( iCode, (Word16) iDifference );
+ iIndex = L_and( iIndex, iMask );
+ poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables );
+ iCurrentLength = L_sub( iCurrentLength, iReadLength );
+ }
+
+ iMask = L_sub( L_shl( 1, (Word16) iCurrentLength ), 1 );
+ iDifference = L_sub( iReadLength, iCurrentLength );
+ iCodeLow = L_shl( L_and( iCode, iMask ), (Word16) iDifference );
+ iMask = L_sub( L_shl( 1, (Word16) iDifference ), 1 );
+ iCodeHigh = L_or( iCodeLow, iMask );
+ FOR( iIndex = iCodeLow; iIndex <= iCodeHigh; iIndex++ )
+ {
+ poNode->piCodeIndex[iIndex] = iCodeIndex;
+ move32();
+ poNode->piDifference[iIndex] = iDifference;
+ move32();
+ poNode->piLength[iIndex] = iLength;
+ move32();
+ }
+}
+
+static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables )
+{
+ Word32 n;
+ UWord32 **ppsort_enc_table;
+ TableList *ptable_list;
+ ptable_list = (TableList *) malloc( sizeof( TableList ) );
+
+ ppsort_enc_table = (UWord32 **) malloc( iSize * sizeof( Word32 * ) );
+ FOR( n = 0; n < iSize; n++ )
+ {
+ ppsort_enc_table[n] = (UWord32 *) malloc( 3 * sizeof( Word32 ) );
+ ppsort_enc_table[n][0] = (UWord32) ppuiEncTable[n][0];
+ move32();
+ ppsort_enc_table[n][1] = (UWord32) ppuiEncTable[n][1];
+ move32();
+ ppsort_enc_table[n][2] = (UWord32) n;
+ move32();
+ }
+
+ FOR( n = 0; n < iSize; n++ )
+ {
+ UWord32 iMin;
+ Word32 iMinIndex;
+ Word32 k;
+
+ iMin = ppsort_enc_table[n][0];
+ move32();
+ iMinIndex = n;
+ move32();
+ FOR( k = n; k < iSize; k++ )
+ {
+ IF( ppsort_enc_table[k][0] < iMin )
+ {
+ iMin = ppsort_enc_table[k][0];
+ move32();
+ iMinIndex = k;
+ move32();
+ }
+ }
+
+ IF( NE_32( iMinIndex, n ) )
+ {
+ UWord32 uiLength;
+ UWord32 uiCode;
+ UWord32 uiCodeIndex;
+
+ uiLength = ppsort_enc_table[n][0];
+ move32();
+ uiCode = ppsort_enc_table[n][1];
+ move32();
+ uiCodeIndex = ppsort_enc_table[n][2];
+ move32();
+
+ ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0];
+ move32();
+ ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1];
+ move32();
+ ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2];
+ move32();
+
+ ppsort_enc_table[iMinIndex][0] = uiLength;
+ move32();
+ ppsort_enc_table[iMinIndex][1] = uiCode;
+ move32();
+ ppsort_enc_table[iMinIndex][2] = uiCodeIndex;
+ move32();
+ }
+ }
+ ptable_list->poOrderedTop = CreateTableList( iReadLength );
+ ptable_list->poOrderedBottom = ptable_list->poOrderedTop;
+ FOR( n = 0; n < iSize; n++ )
+ {
+ Word32 iLength;
+ Word32 iCode;
+ Word32 iCodeIndex;
+
+ iLength = ppsort_enc_table[n][0];
+ move32();
+ iCode = ppsort_enc_table[n][1];
+ move32();
+ iCodeIndex = ppsort_enc_table[n][2];
+ move32();
+ AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength,
+ iTables );
+ }
+
+ CompleteTables( psLCLDDecoder, num, ptable_list, iReadLength, *iTables );
+ DeleteTableList( ptable_list, *iTables );
+ FOR( n = 0; n < iSize; n++ )
+ {
+ free( ppsort_enc_table[n] );
+ }
+ free( ppsort_enc_table );
+}
+
+
+/*------------------------------------------------------------------------------------------*
+ * Function CreateLCLDDecoder()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+ivas_error CreateLCLDDecoder(
+ LCLDDecoder **psLCLDDecoder_out,
+ const Word32 iSampleRate,
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ const Word32 iRealOnlyOut )
+{
+ Word32 n;
+ Word32 read_length;
+ ivas_error error;
+ LCLDDecoder *psLCLDDecoder = NULL;
+
+ assert( iSampleRate == 48000 );
+ assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 );
+ IF( ( psLCLDDecoder = (LCLDDecoder *) malloc( sizeof( LCLDDecoder ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ psLCLDDecoder->iSampleRate = iSampleRate;
+ move32();
+ psLCLDDecoder->iChannels = iChannels;
+ psLCLDDecoder->iAllocOffset = 0;
+ psLCLDDecoder->iRealOnlyOut = iRealOnlyOut;
+ if ( iRealOnlyOut == 1 )
+ {
+ psLCLDDecoder->iNumBlocks = L_shr( iNumBlocks, 1 );
+ }
+ else
+ {
+ psLCLDDecoder->iNumBlocks = iNumBlocks;
+ }
+ psLCLDDecoder->iNumBands = 0; /* read from bitstream*/
+ move32();
+ psLCLDDecoder->piBandwidths = c_aiBandwidths48;
+
+ psLCLDDecoder->iMSMode = 0;
+ move32();
+ IF( ( psLCLDDecoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ FOR( n = 0; n < MAX_BANDS; n++ )
+ {
+ psLCLDDecoder->piLRPhaseDiffs[n] = 0;
+ move32();
+ psLCLDDecoder->piMSPredCoefs[n] = 0;
+ move32();
+ }
+
+ psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */
+ move32();
+ IF( ( psLCLDDecoder->piNumGroups = (Word32 *) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->ppiGroupLengths = (Word32 **) malloc( psLCLDDecoder->iChannels * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiSMR = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiExcitation = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiAlloc = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDDecoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word16 k;
+ IF( ( psLCLDDecoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDDecoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ IF( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDDecoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( psLCLDDecoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ }
+ }
+
+ read_length = READ_LENGTH;
+ move32();
+ FOR( n = 0; n < shl( ALLOC_TABLE_SIZE, 1 ); n++ )
+ {
+ psLCLDDecoder->num_decode_table[n] = 1;
+ move32();
+ IF( c_apauiHuffEncTabels[n] != NULL )
+ {
+ CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] );
+ }
+ ELSE
+ {
+ psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL;
+ }
+ }
+
+ IF( ( error = CreatePredictionDecoder_fx( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ psLCLDDecoder->psNoiseGen = NULL; /* CreateNoiseGen(); No noise fill for now*/
+ *psLCLDDecoder_out = psLCLDDecoder;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*------------------------------------------------------------------------------------------*
+ * Function DeleteLCLDDecoder()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder )
+{
+ Word32 k, n;
+
+ IF( psLCLDDecoder != NULL )
+ {
+ IF( psLCLDDecoder->piMSFlags != NULL )
+ {
+ free( psLCLDDecoder->piMSFlags );
+ }
+
+ IF( psLCLDDecoder->piNumGroups != NULL )
+ {
+ free( psLCLDDecoder->piNumGroups );
+ }
+
+ IF( psLCLDDecoder->ppiGroupLengths != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ free( psLCLDDecoder->ppiGroupLengths[n] );
+ }
+ free( psLCLDDecoder->ppiGroupLengths );
+ }
+
+ IF( psLCLDDecoder->pppiRMSEnvelope != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiRMSEnvelope[n][k] );
+ }
+ free( psLCLDDecoder->pppiRMSEnvelope[n] );
+ }
+ free( psLCLDDecoder->pppiRMSEnvelope );
+ }
+
+ IF( psLCLDDecoder->pppiSMR != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiSMR[n][k] );
+ }
+ free( psLCLDDecoder->pppiSMR[n] );
+ }
+ free( psLCLDDecoder->pppiSMR );
+ }
+
+ IF( psLCLDDecoder->pppiExcitation != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiExcitation[n][k] );
+ }
+ free( psLCLDDecoder->pppiExcitation[n] );
+ }
+ free( psLCLDDecoder->pppiExcitation );
+ }
+
+
+ IF( psLCLDDecoder->pppiAlloc != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiAlloc[n][k] );
+ }
+ free( psLCLDDecoder->pppiAlloc[n] );
+ }
+ free( psLCLDDecoder->pppiAlloc );
+ }
+
+ IF( psLCLDDecoder->pppiLCLDSignReal != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiLCLDSignReal[n][k] );
+ }
+ free( psLCLDDecoder->pppiLCLDSignReal[n] );
+ }
+ free( psLCLDDecoder->pppiLCLDSignReal );
+ }
+
+ IF( psLCLDDecoder->pppiLCLDSignImag != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiLCLDSignImag[n][k] );
+ }
+ free( psLCLDDecoder->pppiLCLDSignImag[n] );
+ }
+ free( psLCLDDecoder->pppiLCLDSignImag );
+ }
+
+ IF( psLCLDDecoder->pppiQLCLDReal != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiQLCLDReal[n][k] );
+ }
+ free( psLCLDDecoder->pppiQLCLDReal[n] );
+ }
+ free( psLCLDDecoder->pppiQLCLDReal );
+ }
+
+ IF( psLCLDDecoder->pppiQLCLDImag != NULL )
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDDecoder->pppiQLCLDImag[n][k] );
+ }
+ free( psLCLDDecoder->pppiQLCLDImag[n] );
+ }
+ free( psLCLDDecoder->pppiQLCLDImag );
+ }
+
+ FOR( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ )
+ {
+ IF( psLCLDDecoder->num_decode_table[n] > 1 )
+ {
+
+ IF( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL )
+ {
+ free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] );
+ }
+ }
+ }
+
+ IF( psLCLDDecoder->psPredictionDecoder != NULL )
+ {
+ DeletePredictionDecoder_fx( psLCLDDecoder->psPredictionDecoder );
+ psLCLDDecoder->psPredictionDecoder = NULL;
+ }
+
+ IF( psLCLDDecoder->psNoiseGen != NULL )
+ {
+ DeleteNoiseGen( psLCLDDecoder->psNoiseGen );
+ }
+
+ free( psLCLDDecoder );
+ }
+}
+
+/*------------------------------------------------------------------------------------------*
+ * Local function declarations
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+static void ApplyRMSEnvelope_fx( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx );
+static void ReplaceSign_fx( const Word32 iNumBlocks, const Word32 iNumLCLDBands, Word32 **ppiSignReal, Word32 **ppiSignImag, Word32 **ppfReal, Word32 **ppfImag, const Word32 *piBandwidths );
+
+static void InvQuantizeSpectrum_fx( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag, Word32 **ppfReal, Word32 **ppfImag, NoiseGen *psNoiseGen );
+static void InvMSCoding_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiffs, const Word32 *piMSPredCoefs, Word32 ***pppfReal, Word32 ***pppfImag );
+// static void InvMSCoding_fx( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx,Word16 exp );
+
+static Word32 ReadHeaderInformation( Word32 *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 ReadMSInformation( const Word32 iNumBands, Word32 *piMSMode, Word32 *piMSFlags, Word32 *piLRPhaseDiffs, Word32 *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 ReadGroupInformation( const Word32 iChannels, const Word32 iNumBlocks, Word32 *piCommonGrouping, Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 ReadHuff( const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], Word32 *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 ReadRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 ReadAllocInformation( Word32 *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+// static int32_t
+// ReadLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] );
+static Word32 ReadLCLDData_fx( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiDecodingUnresolved, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] );
+static void ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiSMR, const Word32 iAllocOffset, Word32 ***pppiAlloc );
+
+void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder )
+{
+ int32_t n, ch;
+ PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1;
+ psPredictionDecoder->ppiDecodingFailed[ch][n] = 1;
+ psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1;
+ }
+ }
+}
+
+int32_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder )
+{
+ int32_t n, ch;
+ PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 )
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int32_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder )
+{
+ int32_t n, ch;
+ PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder;
+ for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ )
+ {
+ for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ )
+ {
+ if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 )
+ {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder )
+{
+ return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed;
+}
+
+int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder )
+{
+ return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets;
+}
+
+int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder )
+{
+ return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev;
+}
+
+static void UnpackReal_fx(
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx )
+{
+ Word32 ch, b, n;
+ FOR( ch = 0; ch < iChannels; ch++ )
+ {
+ FOR( b = 0; b < LCLD_BANDS; b++ )
+ {
+ Word32 iRealBlock = iNumBlocks - 1;
+ FOR( n = iNumBlocks / 2 - 1; n >= 0; n-- )
+ {
+ pppfReal_fx[ch][iRealBlock][b] = L_shl( pppfImag_fx[ch][n][b], 1 );
+ pppfReal_fx[ch][iRealBlock - 1][b] = L_shl( pppfReal_fx[ch][n][b], 1 );
+ pppfImag_fx[ch][iRealBlock][b] = 0;
+ pppfImag_fx[ch][iRealBlock - 1][b] = 0;
+ iRealBlock -= 2;
+ }
+ }
+ }
+}
+/*------------------------------------------------------------------------------------------*
+ * Function DecodeLCLDFrame()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+Word32 DecodeLCLDFrame(
+ LCLDDecoder *psLCLDDecoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 ***pppfLCLDReal_fx,
+ Word32 ***pppfLCLDImag_fx,
+ Word16 Q_in,
+ Word16 *Q_out )
+{
+ Word32 k, n;
+ // FILE *ptr = fopen( "cldfb_real.txt", "ab+" );
+ // FILE *ptr1 = fopen( "cldfb_imag.txt", "ab+" );
+ ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits );
+
+ IF( EQ_32( psLCLDDecoder->iChannels, 2 ) )
+ {
+ ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits );
+ }
+
+ Word16 i, j;
+
+ ReadPredictors_fx( psLCLDDecoder->psPredictionDecoder, pBits );
+
+ UpdateDecodingUnresolved( psLCLDDecoder->psPredictionDecoder );
+ UpdateDecodingFailedStatus( psLCLDDecoder->psPredictionDecoder );
+
+ ReadGroupInformation( psLCLDDecoder->iChannels, psLCLDDecoder->iNumBlocks, &psLCLDDecoder->iCommonGrouping, psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, pBits );
+
+ ReadRMSEnvelope( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits );
+
+
+ ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits );
+
+ IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && EQ_32( psLCLDDecoder->iCommonGrouping, 1 ) )
+ { /* MS Mode? */
+ FOR( k = 0; k < psLCLDDecoder->piNumGroups[0]; k++ )
+ {
+ PerceptualModelStereo_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piMSFlags,
+ psLCLDDecoder->pppiRMSEnvelope[0][k],
+ psLCLDDecoder->pppiRMSEnvelope[1][k],
+ psLCLDDecoder->pppiExcitation[0][k],
+ psLCLDDecoder->pppiExcitation[1][k],
+ psLCLDDecoder->pppiSMR[0][k],
+ psLCLDDecoder->pppiSMR[1][k] );
+ }
+ }
+ ELSE
+ {
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ { /* This will be updated to support multiple sample rates*/
+ FOR( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ )
+ {
+ PerceptualModel_fx( (Word16) psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] );
+ }
+ }
+ }
+
+ ComputeAllocation( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc );
+
+ ReadLCLDData_fx(
+ psLCLDDecoder->piNumGroups,
+ psLCLDDecoder->ppiGroupLengths,
+ psLCLDDecoder->iNumBands,
+ psLCLDDecoder->iChannels,
+ psLCLDDecoder->psPredictionDecoder->ppiDecodingUnresolved,
+ psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable,
+ psLCLDDecoder->psPredictionDecoder->iNumSubSets,
+ psLCLDDecoder->psPredictionDecoder->iSubSetId,
+ psLCLDDecoder->pppiAlloc,
+ psLCLDDecoder->pppiLCLDSignReal,
+ psLCLDDecoder->pppiLCLDSignImag,
+ psLCLDDecoder->pppiQLCLDReal,
+ psLCLDDecoder->pppiQLCLDImag,
+ psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed,
+ pBits,
+ psLCLDDecoder->c_apauiHuffDecTable_RAM );
+ Word16 q_LCLD = Q_in;
+
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ InvQuantizeSpectrum_fx( psLCLDDecoder->piNumGroups[n],
+ (const Word32 *) psLCLDDecoder->ppiGroupLengths[n],
+ psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths,
+ psLCLDDecoder->pppiAlloc[n],
+ psLCLDDecoder->pppiQLCLDReal[n],
+ psLCLDDecoder->pppiQLCLDImag[n],
+ pppfLCLDReal_fx[n], pppfLCLDImag_fx[n],
+ psLCLDDecoder->psNoiseGen );
+
+ ReplaceSign_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands,
+ psLCLDDecoder->pppiLCLDSignReal[n],
+ psLCLDDecoder->pppiLCLDSignImag[n],
+ pppfLCLDReal_fx[n], pppfLCLDImag_fx[n], psLCLDDecoder->piBandwidths );
+ }
+#ifdef DEBUG_WRITE_PREDICTORS
+ {
+ static FILE *fid;
+ if ( !fid )
+ fid = fopen( "pred_dec.txt", "wt" );
+ for ( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ int16_t b;
+ for ( b = 0; b < 60; b++ )
+ fprintf( fid, "%.5f ", (float) psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n][b] * psLCLDDecoder->psPredictionDecoder->ppfA1Imag[n][b] );
+ }
+ fprintf( fid, "%d %d\n", psLCLDDecoder->psPredictionDecoder->iSubSetId, psLCLDDecoder->psPredictionDecoder->piPredChanEnable[n] );
+ }
+#endif
+
+ ApplyInversePredictors_fx( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal_fx, pppfLCLDImag_fx );
+
+#ifdef DEBUG_WRITE
+ FOR( n = 0; n < psLCLDDecoder->psPredictionDecoder->iChannels; ++n )
+ {
+ FOR( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ )
+ {
+ dbgwrite_txt( pppfLCLDReal[n][i], LCLD_BANDS, "LCLD_real_ApplyInversePredictors_fix.txt", NULL );
+ dbgwrite_txt( pppfLCLDImag[n][i], LCLD_BANDS, "LCLD_imag_ApplyInversePredictors_fix.txt", NULL );
+ }
+ }
+
+ FOR( i = 0; i < psLCLDDecoder->psPredictionDecoder->iChannels; ++i )
+ {
+ dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateReal[i], LCLD_BANDS, "LCLD_Pred_stat_real_ApplyInversePredictors_fix.txt", NULL );
+ dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateImag[i], LCLD_BANDS, "LCLD_Pred_stat_imag_ApplyInversePredictors_fix.txt", NULL );
+ }
+
+#endif
+
+ Word16 Q = 7;
+ *Q_out = Q;
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], Q - q_LCLD );
+ pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], Q - q_LCLD );
+ }
+ }
+ ApplyRMSEnvelope_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths,
+ psLCLDDecoder->piNumGroups[n],
+ (const Word32 *) psLCLDDecoder->ppiGroupLengths[n],
+ psLCLDDecoder->pppiRMSEnvelope[n],
+ pppfLCLDReal_fx[n], pppfLCLDImag_fx[n] );
+ }
+
+ IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && GT_32( psLCLDDecoder->iMSMode, 0 ) )
+ {
+ Word16 exp1 = Q31 - *Q_out;
+ Word16 exp2 = Q31 - *Q_out;
+ Word32 real_max = 0;
+ Word32 imag_max = 0;
+ Word16 exp;
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ real_max = L_max( real_max, L_abs( pppfLCLDReal_fx[n][i][j] ) );
+ imag_max = L_max( imag_max, L_abs( pppfLCLDImag_fx[n][i][j] ) );
+ }
+ }
+ }
+ IF( NE_32( real_max, 0 ) )
+ {
+ exp1 = s_min( exp1, norm_l( real_max ) );
+ }
+ IF( NE_32( imag_max, 0 ) )
+ {
+ exp2 = s_min( exp2, norm_l( imag_max ) );
+ }
+ IF( NE_32( real_max, 0 ) || NE_32( imag_max, 0 ) )
+ {
+ exp = min( exp2, exp1 );
+ *Q_out = add( *Q_out, sub( exp, 3 ) );
+ FOR( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], exp - 3 );
+ pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], exp - 3 );
+ }
+ }
+ }
+ }
+ InvMSCoding_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands,
+ psLCLDDecoder->piBandwidths, psLCLDDecoder->iMSMode,
+ (const Word32 *) psLCLDDecoder->piMSFlags,
+ (const Word32 *) psLCLDDecoder->piLRPhaseDiffs,
+ (const Word32 *) psLCLDDecoder->piMSPredCoefs,
+ pppfLCLDReal_fx, pppfLCLDImag_fx );
+
+#ifdef DEBUG_WRITE
+ for ( n = 0; n < psLCLDDecoder->iChannels; n++ )
+ {
+ Word32 pppfLCLDReal_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ Word32 pppfLCLDImag_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ for ( i = 0; i < psLCLDDecoder->iNumBlocks; i++ )
+ {
+ for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ pppfLCLDReal_dbg[n][i][j] = (float) pppfLCLDReal_fx[n][i][j] / ( 1 << ( exp - 3 ) );
+ pppfLCLDImag_dbg[n][i][j] = (float) pppfLCLDImag_fx[n][i][j] / ( 1 << ( exp - 3 ) );
+ }
+ }
+ {
+ for ( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ )
+ {
+ dbgwrite_txt( pppfLCLDReal_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_real_Inv_MS.txt", NULL );
+ dbgwrite_txt( pppfLCLDImag_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_imag_Inv_MS.txt", NULL );
+ }
+ }
+ }
+#endif
+ }
+ IF( EQ_32( psLCLDDecoder->iRealOnlyOut, 1 ) )
+ {
+ UnpackReal_fx( psLCLDDecoder->iChannels,
+ psLCLDDecoder->iNumBlocks * 2,
+ pppfLCLDReal_fx,
+ pppfLCLDImag_fx );
+ }
+
+ return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder );
+}
+/*------------------------------------------------------------------------------------------*
+ * Local functions
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+static void ApplyRMSEnvelope_fx(
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ Word32 **ppiRMSEnvelope,
+ Word32 **ppfReal_fx,
+ Word32 **ppfImag_fx )
+{
+ Word32 b, k, n;
+
+#ifdef DEBUG
+ FILE *fp_real, *fp_imag, *fp_real_fx, *fp_imag_fx, *fp_real_inp, *fp_imag_inp, *fp_real_inp_fx, *fp_imag_inp_fx;
+ fp_real = fopen( "Float_code_real1.txt", "ab+" );
+ fp_imag = fopen( "Float_code_imag1.txt", "ab+" );
+ fp_real_fx = fopen( "Fixed_code_real1.txt", "ab+" );
+ fp_imag_fx = fopen( "Fixed_code_imag1.txt", "ab+" );
+ fp_real_inp = fopen( "real_input.txt", "ab+" );
+ fp_imag_inp = fopen( "imag_input.txt", "ab+" );
+#endif
+
+ Word32 iBlockOffset, iFBOffset;
+
+ iBlockOffset = 0;
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ iFBOffset = 0;
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 m;
+ Word32 iRMSEnv;
+ Word32 fGain_fx;
+ Word16 fGain_exp;
+
+ iRMSEnv = ppiRMSEnvelope[n][b];
+ IF( ( ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv ) % 2 == 0 )
+ {
+ fGain_fx = 1073741824; // 2 ^ 30
+ }
+ ELSE
+ {
+ fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30
+ }
+ fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv];
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ Word64 tmp;
+#ifdef DEBUG
+ fprintf( fp_real_inp, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] );
+ fprintf( fp_imag_inp, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] );
+#endif
+
+#ifdef DEBUG
+ fprintf( fp_real, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] );
+ fprintf( fp_imag, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] );
+#endif
+ tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] );
+ tmp = W_shr( tmp, fGain_exp + 1 );
+ ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
+
+ tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] );
+ tmp = W_shr( tmp, fGain_exp + 1 );
+ ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
+
+#ifdef DEBUG
+ fprintf( fp_real_fx, "%.6f\n", (float) ppfReal_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) );
+ fprintf( fp_imag_fx, "%.6f\n", (float) ppfImag_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) );
+#endif
+
+ iFBOffset++;
+ }
+ }
+ iBlockOffset++;
+ }
+ }
+#ifdef DEBUG
+ fclose( fp_real );
+ fclose( fp_imag );
+ fclose( fp_imag_fx );
+ fclose( fp_real_fx );
+ fclose( fp_real_inp );
+ fclose( fp_imag_inp );
+#endif
+
+ return;
+}
+
+static void ReplaceSign_fx(
+ const Word32 iNumBlocks,
+ const Word32 iNumLCLDBands,
+ Word32 **ppiSignReal,
+ Word32 **ppiSignImag,
+ Word32 **ppfReal,
+ Word32 **ppfImag,
+ const Word32 *piBandwidths )
+{
+ Word32 b, n;
+ Word32 m, idx;
+
+ FOR( n = 0; n < iNumBlocks; n++ )
+ {
+ idx = 0;
+ move32();
+ FOR( b = 0; b < iNumLCLDBands; b++ )
+ {
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ IF( EQ_32( ppiSignReal[n][idx], 1 ) )
+ {
+ ppfReal[n][idx] = L_negate( ppfReal[n][idx] );
+ move32();
+ }
+
+ IF( EQ_32( ppiSignImag[n][idx], 1 ) )
+ {
+ ppfImag[n][idx] = L_negate( ppfImag[n][idx] );
+ move32();
+ }
+ idx++;
+ }
+ }
+ }
+ return;
+}
+
+static void InvQuantizeSpectrum_fx(
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 **ppiAlloc,
+ Word32 **ppiQReal,
+ Word32 **ppiQImag,
+ Word32 **ppfReal,
+ Word32 **ppfImag,
+ NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */
+)
+{
+ Word32 b, k, n;
+ Word32 iBlockOffest, iFBOffset;
+
+ iBlockOffest = 0;
+ move32();
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ iFBOffset = 0;
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 m;
+ Word32 iAlloc;
+ Word32 fInvSCFGain;
+
+ iAlloc = ppiAlloc[n][b];
+ move32();
+ fInvSCFGain = c_afInvScaleFactor_fx[iAlloc]; // Q29
+ move32();
+ IF( GT_32( iAlloc, 0 ) )
+ {
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ Word16 iQuantValue;
+
+ iQuantValue = (Word16) ppiQReal[iBlockOffest][iFBOffset];
+ move16();
+ ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14
+ move32();
+ iQuantValue = (Word16) ppiQImag[iBlockOffest][iFBOffset];
+ move16();
+ ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14
+ move32();
+ iFBOffset++;
+ }
+ }
+ ELSE IF( psNoiseGen != NULL )
+ {
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14 + 15 -15 )=Q14
+ move32();
+ ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14+ 15 -15 )=Q14
+ move32();
+ iFBOffset++;
+ }
+ }
+ ELSE
+ {
+ iFBOffset = L_add( iFBOffset, piBandwidths[b] );
+ move32();
+ }
+ }
+
+ iBlockOffest++;
+ }
+ }
+
+ return;
+}
+
+static void InvMSCoding_fx(
+ const Word32 iNumBlocks,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ const Word32 iMSMode,
+ const Word32 *piMSFlags,
+ const Word32 *piLRPhaseDiffs,
+ const Word32 *piMSPredCoefs,
+ Word32 ***pppfReal,
+ Word32 ***pppfImag )
+{
+
+ IF( GT_32( iMSMode, 0 ) )
+ {
+ Word32 b;
+ Word32 iFBOffset;
+ Word32 bMSPred = 0;
+ move32();
+
+ iFBOffset = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ IF( EQ_32( piMSFlags[b], 1 ) )
+ {
+ Word32 n;
+ Word32 phaseIdx;
+
+ Word32 fPred;
+
+ phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL;
+ move32();
+ fPred = dequantPred_fx( piMSPredCoefs[bMSPred] );
+ move32();
+ FOR( n = 0; n < piBandwidths[b]; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < iNumBlocks; k++ )
+ {
+ Word32 fLeftReal;
+ Word32 fLeftImag;
+ Word32 fRightReal;
+ Word32 fRightImag;
+
+ IF( EQ_32( iMSMode, 3 ) )
+ {
+ pppfReal[1][k][iFBOffset] = L_add( pppfReal[1][k][iFBOffset], Mpy_32_32( fPred, pppfReal[0][k][iFBOffset] ) );
+ move32();
+ pppfImag[1][k][iFBOffset] = L_add( pppfImag[1][k][iFBOffset], Mpy_32_32( fPred, pppfImag[0][k][iFBOffset] ) );
+ move32();
+ }
+
+ fLeftReal = L_add( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] );
+ fLeftImag = L_add( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] );
+ fRightReal = L_sub( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] );
+ fRightImag = L_sub( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] );
+
+ IF( EQ_32( iMSMode, 3 ) )
+ {
+ cplxmult_fx( &fRightReal, &fRightImag, c_afRotRealImag_fx[phaseIdx][0], -c_afRotRealImag_fx[phaseIdx][1] );
+ }
+
+ pppfReal[0][k][iFBOffset] = fLeftReal;
+ move32();
+ pppfReal[1][k][iFBOffset] = fRightReal;
+ move32();
+ pppfImag[0][k][iFBOffset] = fLeftImag;
+ move32();
+ pppfImag[1][k][iFBOffset] = fRightImag;
+ move32();
+ }
+ iFBOffset++;
+ }
+ bMSPred++;
+ }
+ ELSE
+ {
+ iFBOffset = L_add( iFBOffset, piBandwidths[b] );
+ move32();
+ }
+ }
+ }
+
+ return;
+}
+
+/* Currently only the number of bands in frame */
+static Word32 ReadHeaderInformation(
+ Word32 *piNumBands,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsRead;
+
+ iBitsRead = 0;
+ move32();
+ *piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 );
+ iBitsRead = L_add( iBitsRead, 5 );
+
+ return iBitsRead;
+}
+
+
+static Word32 ReadMSInformation(
+ const Word32 iNumBands,
+ Word32 *piMSMode,
+ Word32 *piMSFlags,
+ Word32 *piLRPhaseDiffs,
+ Word32 *piMSPredCoefs,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsRead;
+
+ iBitsRead = 0;
+ move32();
+ *piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 );
+ iBitsRead = L_add( iBitsRead, 2 );
+
+ IF( EQ_32( *piMSMode, 0 ) )
+ {
+ Word32 n;
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ piMSFlags[n] = 0;
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( *piMSMode, 1 ) )
+ {
+ Word32 n;
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ piMSFlags[n] = 1;
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( *piMSMode, 2 ) )
+ {
+ Word32 n;
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = L_add( iBitsRead, 1 );
+ }
+ }
+ ELSE IF( EQ_32( *piMSMode, 3 ) )
+ {
+ Word32 n;
+ Word32 iMSPredAll;
+ Word32 iNumMSPredBands = 0;
+ Word32 anyNonZero;
+ move32();
+ iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ iBitsRead = L_add( iBitsRead, 1 );
+ IF( iMSPredAll )
+ {
+ iNumMSPredBands = iNumBands;
+ move32();
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ piMSFlags[n] = 1;
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = L_add( iBitsRead, 1 );
+ IF( piMSFlags[n] )
+ {
+ iNumMSPredBands++;
+ }
+ }
+ }
+ anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ IF( anyNonZero )
+ {
+ piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS );
+ move32();
+ piLRPhaseDiffs[0] = L_add( piLRPhaseDiffs[0], PHASE_MIN_VAL );
+ move32();
+ iBitsRead = L_add( iBitsRead, PHASE_BAND0_BITS );
+ FOR( n = 1; n < iNumMSPredBands; n++ )
+ {
+ Word32 tabIdx;
+ iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) );
+ piLRPhaseDiffs[n] = L_add( tabIdx, ENV_DELTA_MIN );
+ move32();
+ }
+ DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM );
+ }
+ ELSE
+ {
+ FOR( n = 0; n < iNumMSPredBands; n++ )
+ {
+ piLRPhaseDiffs[n] = 0;
+ move32();
+ }
+ }
+ anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ IF( anyNonZero )
+ {
+ piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS );
+ move32();
+ piMSPredCoefs[0] = L_add( piMSPredCoefs[0], PRED_MIN_VAL );
+ move32();
+ iBitsRead = L_add( iBitsRead, PRED_BAND0_BITS );
+ FOR( n = 1; n < iNumMSPredBands; n++ )
+ {
+ Word32 tabIdx;
+ iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) );
+ piMSPredCoefs[n] = L_add( tabIdx, ENV_DELTA_MIN );
+ move32();
+ }
+ DecodePredCoef( piMSPredCoefs, iNumMSPredBands );
+ }
+ ELSE
+ {
+ FOR( n = 0; n < iNumMSPredBands; n++ )
+ {
+ piMSPredCoefs[n] = 0;
+ move32();
+ }
+ }
+#ifdef DEBUG_WRITE_MS_PRED
+ {
+ static FILE *fid;
+ IF( !fid )
+ fid = fopen( "ms_pred_dec.txt", "wt" );
+ writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags );
+ }
+#endif
+ }
+ ELSE
+ {
+ printf( "ERROR UNSUPPORTED MS MODE\n" );
+ }
+
+ return iBitsRead;
+}
+
+static Word32 ReadGroupInformation(
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ Word32 *piCommonGrouping,
+ Word32 *piNumGroups,
+ Word32 **ppiGroupLengths,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 c, k, iBitsRead;
+
+ iBitsRead = 0;
+ move32();
+ IF( EQ_32( iChannels, 2 ) )
+ {
+ *piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = L_add( iBitsRead, 1 );
+
+ IF( EQ_32( *piCommonGrouping, 1 ) )
+ {
+ piNumGroups[0] = 0;
+ move32();
+ ppiGroupLengths[0][piNumGroups[0]] = 1;
+ move32();
+ FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ )
+ {
+ Word32 iGroupStart;
+
+ iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ iBitsRead = L_add( iBitsRead, 1 );
+
+ IF( EQ_32( iGroupStart, 1 ) )
+ {
+ piNumGroups[0] = L_add( piNumGroups[0], 1 );
+ move32();
+ ppiGroupLengths[0][piNumGroups[0]] = 1;
+ move32();
+ }
+ ELSE
+ {
+ ppiGroupLengths[0][piNumGroups[0]] = L_add( ppiGroupLengths[0][piNumGroups[0]], 1 );
+ move32();
+ }
+ }
+ piNumGroups[0] = L_add( piNumGroups[0], 1 );
+ move32();
+
+ piNumGroups[1] = piNumGroups[0];
+ move32();
+ FOR( k = 0; k < piNumGroups[1]; k++ )
+ {
+ ppiGroupLengths[1][k] = ppiGroupLengths[0][k];
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR( c = 0; c < iChannels; c++ )
+ {
+ piNumGroups[c] = 0;
+ move32();
+ ppiGroupLengths[c][piNumGroups[c]] = 1;
+ move32();
+ FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ )
+ {
+ Word32 iGroupStart;
+
+ iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ iBitsRead = L_add( iBitsRead, 1 );
+
+ IF( EQ_32( iGroupStart, 1 ) )
+ {
+ piNumGroups[c] = L_add( piNumGroups[c], 1 );
+ move32();
+ ppiGroupLengths[c][piNumGroups[c]] = 1;
+ move32();
+ }
+ ELSE
+ {
+ ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 );
+ move32();
+ }
+ }
+ piNumGroups[c] = L_add( piNumGroups[c], 1 );
+ move32();
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( c = 0; c < iChannels; c++ )
+ {
+ piNumGroups[c] = 0;
+ move32();
+ ppiGroupLengths[c][piNumGroups[c]] = 1;
+ move32();
+ FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ )
+ {
+ Word32 iGroupStart;
+
+ iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ iBitsRead = L_add( iBitsRead, 1 );
+
+ IF( EQ_32( iGroupStart, 1 ) )
+ {
+ piNumGroups[c] = L_add( piNumGroups[c], 1 );
+ move32();
+ ppiGroupLengths[c][piNumGroups[c]] = 1;
+ move32();
+ }
+ ELSE
+ {
+ ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 );
+ }
+ }
+ piNumGroups[c] = L_add( piNumGroups[c], 1 );
+ }
+ }
+
+ return iBitsRead;
+}
+
+static Word32 BSForceBack(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 iValue,
+ Word32 iBitCount )
+{
+ pBits->bits_read = L_sub( pBits->bits_read, iBitCount );
+
+ return ( L_shr( iValue, (Word16) iBitCount ) );
+}
+
+
+static Word32 ReadHuff(
+ const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE],
+ Word32 *piSymbol,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsRead;
+ Word32 iSymbol;
+ Word32 iIndex;
+ Word32 iVal;
+
+ iVal = 0;
+ move32();
+ iIndex = 0;
+ move32();
+ iSymbol = 0xFFFF;
+ move32();
+ iBitsRead = 0;
+ move32();
+ WHILE( iSymbol == 0xFFFF )
+ {
+ iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE );
+ iBitsRead = L_add( iBitsRead, HUFF_READ_SIZE );
+
+ iIndex = pauiHuffDecTable[iVal][iIndex];
+ iSymbol = ( L_and( iIndex, 0xFFFF ) );
+
+ iVal = ( L_shr( iIndex, 16 ) );
+ }
+
+ IF( iVal )
+ {
+ BSForceBack( pBits, iIndex, iVal );
+ iBitsRead = L_sub( iBitsRead, iVal );
+ }
+
+ *piSymbol = iSymbol;
+ move32();
+
+ return iBitsRead;
+}
+
+
+static Word32 ReadRMSEnvelope(
+ const Word32 iChannels,
+ const Word32 *piNumGroups,
+ const Word32 iNumBands,
+ Word32 ***pppiRMSEnvelope,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 b, k, n;
+ Word32 iBitsRead, iLastRMSVal;
+
+ iBitsRead = 0;
+ move32();
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ FOR( k = 0; k < piNumGroups[n]; k++ )
+ {
+ iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS );
+ iBitsRead = L_add( iBitsRead, ENV0_BITS );
+
+ iLastRMSVal = L_add( iLastRMSVal, ENV_MIN );
+ pppiRMSEnvelope[n][k][0] = iLastRMSVal;
+ move32();
+ FOR( b = 1; b < iNumBands; b++ )
+ {
+ Word32 iDelta;
+
+ iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ) );
+
+ iDelta = L_add( iDelta, ENV_DELTA_MIN );
+ iLastRMSVal = L_add( iDelta, iLastRMSVal );
+ pppiRMSEnvelope[n][k][b] = iLastRMSVal;
+ move32();
+ }
+ }
+ }
+
+ return iBitsRead;
+}
+
+
+static Word32 ReadAllocInformation(
+ Word32 *piAllocOffset,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsRead;
+
+ iBitsRead = 0;
+ move32();
+ *piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS );
+ *piAllocOffset = L_add( *piAllocOffset, MIN_ALLOC_OFFSET );
+ iBitsRead = L_add( iBitsRead, ALLOC_OFFSET_BITS );
+
+ return iBitsRead;
+}
+
+static Word32 ReadLCLDData_fx(
+ const Word32 *piNumGroups,
+ Word32 **ppiGroupLengths,
+ const Word32 iNumBands,
+ const Word32 iNumChannels,
+ Word32 **ppiDecodingUnresolved,
+ Word32 **ppiPredEnable,
+ const Word32 iNumSubSets,
+ const Word32 iSubSetId,
+ Word32 ***pppiAlloc,
+ Word32 ***pppiSignReal,
+ Word32 ***pppiSignImag,
+ Word32 ***pppiQReal,
+ Word32 ***pppiQImag,
+ Word32 **ppiDecodingFailed,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] )
+{
+ Word32 iBitsRead;
+ Word32 iDecodingStopped = 0;
+ Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1];
+ Word32 s;
+ Word32 iSet = iSubSetId;
+ Word16 tmp, tmp_e;
+ iBitsRead = 0;
+ for ( s = 0; s < iNumSubSets; s++, iSet-- )
+ {
+ Word32 ch;
+
+ IF( LT_32( iSet, 0 ) )
+ {
+ iSet = L_sub( iNumSubSets, 1 );
+ }
+
+ FOR( ch = 0; ch < iNumChannels; ch++ )
+ {
+ Word32 n;
+ Word32 iBlockOffest;
+
+ IF( EQ_32( ppiDecodingUnresolved[ch][iSet], 1 ) )
+ {
+ iDecodingStopped = 1;
+ ppiDecodingFailed[ch][iSet] = 1; /* mark as not decoded (is also initialized like that when a frame is lost */
+ }
+ ELSE
+ {
+ ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */
+ }
+ iBlockOffest = 0;
+ FOR( n = 0; n < piNumGroups[ch]; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ )
+ {
+ Word32 iFBOffset;
+
+ FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets )
+ {
+ Word32 b;
+ Word32 iAlloc;
+ Word32 iHuffDim;
+ Word32 iHuffMod;
+
+ b = c_aiBandIdPerLcldBand[iFBOffset];
+
+ iAlloc = pppiAlloc[ch][n][b];
+
+ iHuffDim = c_aiHuffmanDim_fx[iAlloc];
+ iHuffMod = c_aiHuffmanMod_fx[iAlloc];
+
+ IF( EQ_32( iDecodingStopped, 1 ) )
+ {
+ pppiQReal[ch][iBlockOffest][iFBOffset] = 0;
+ pppiQImag[ch][iBlockOffest][iFBOffset] = 0;
+ pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
+ pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
+ }
+ ELSE IF( GT_32( iAlloc, 0 ) )
+ {
+ const UWord32( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL;
+ const UWord32( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL;
+ Word32 iQuantValue1 = 0;
+ Word32 iQuantValue2 = 0;
+#ifdef USE_DEMOD_TABLES
+ const int32_t( *paiDemodTable )[2] = NULL;
+#endif
+ pauiHuffmanTable = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc];
+ pauiHuffmanTableDPCM = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc];
+#ifdef USE_DEMOD_TABLES
+ paiDemodTable = c_apaiDemodTables[iAlloc];
+#endif
+#ifdef LCLD_HANDLE_PRED_START_SAMPLE
+ if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) )
+#else
+ IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) )
+#endif
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ Word32 iSymbol;
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ) );
+#ifdef USE_DEMOD_TABLES
+ iQuantValue1 = paiDemodTable[iSymbol][0];
+ iQuantValue2 = paiDemodTable[iSymbol][1];
+#else
+ tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e );
+ iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) );
+ // iQuantValue1 = iSymbol / iHuffMod;
+ iQuantValue2 = iSymbol % iHuffMod;
+#endif
+ }
+ ELSE
+ {
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ) );
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ) );
+ }
+ }
+ ELSE
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ Word32 iSymbol;
+
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iSymbol, pBits ) );
+#ifdef USE_DEMOD_TABLES
+ iQuantValue1 = paiDemodTable[iSymbol][0];
+ iQuantValue2 = paiDemodTable[iSymbol][1];
+#else
+ tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e );
+ iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) );
+ iQuantValue2 = iSymbol % iHuffMod;
+#endif
+ }
+ ELSE
+ {
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ) );
+ move32();
+ iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ) );
+ move32();
+ /*iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits );
+ iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits );*/
+ }
+ }
+
+ pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1;
+ move32();
+ pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2;
+ move32();
+ IF( GT_32( iQuantValue1, 0 ) )
+ {
+ pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = L_add( iBitsRead, 1 );
+ move32();
+ }
+ ELSE
+ {
+ pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
+ }
+ IF( GT_32( iQuantValue2, 0 ) )
+ {
+ pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ move32();
+ iBitsRead = L_add( iBitsRead, 1 );
+ move32();
+ }
+ ELSE
+ {
+ pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
+ }
+ }
+ ELSE
+ {
+ pppiSignReal[ch][iBlockOffest][iFBOffset] = 0;
+ move32();
+ pppiSignImag[ch][iBlockOffest][iFBOffset] = 0;
+ move32();
+ }
+ }
+ iBlockOffest++;
+ }
+ }
+ }
+ }
+
+ return iBitsRead;
+}
+
+static void ComputeAllocation(
+ const Word32 iChannels,
+ const Word32 *piNumGroups,
+ const Word32 iNumBands,
+ Word32 ***pppiSMR,
+ const Word32 iAllocOffset,
+ Word32 ***pppiAlloc )
+{
+ Word32 b, k, n, iAlloc;
+
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ FOR( k = 0; k < piNumGroups[n]; k++ )
+ {
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ iAlloc = L_shr( L_add( pppiSMR[n][k][b], L_mult0( (Word16) iAllocOffset, ALLOC_OFFSET_SCALE ) ), 5 );
+ iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC;
+ iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC;
+ pppiAlloc[n][k][b] = iAlloc;
+ move32();
+ }
+ }
+ }
+
+ return;
+}
+
+#endif
diff --git a/lib_isar/isar_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..aa9332c26f128b94552bb526fcdea7c0ed5b6e00
--- /dev/null
+++ b/lib_isar/isar_lcld_encoder.c
@@ -0,0 +1,2143 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include
+#include "isar_lcld_prot.h"
+#include "isar_lcld_rom_tables.h"
+#include "prot.h"
+#include "prot_fx2.h"
+#include "isar_prot.h"
+#include "wmc_auto.h"
+#include "basop_util.h"
+#include "enh64.h"
+#include "basop32.h"
+#include "basop_mpy.h"
+
+#define LOG10_2_FX ( 646456993 )
+/*------------------------------------------------------------------------------------------*
+ * Local structures
+ *------------------------------------------------------------------------------------------*/
+struct LCLD_ENCODER
+{
+ Word32 iSampleRate;
+ Word32 iChannels;
+ Word32 iNumBlocks;
+
+ Word32 iTargetBitRate;
+
+ Word32 iNumBands;
+ const Word32 *piBandwidths;
+
+ Word32 iMSMode;
+ Word32 *piMSFlags;
+ Word32 piMSPredCoefs[MAX_BANDS];
+ Word32 piLRPhaseDiffs[MAX_BANDS];
+ Word32 iAllowSidePred;
+
+ Word32 iRealOnlyOut;
+
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping;
+
+ Word32 iCommonGrouping;
+ Word32 *piNumGroups;
+ Word32 **ppiGroupLengths;
+
+ Word32 ***pppiRMSEnvelope;
+ Word32 ***pppiSMR;
+ Word32 ***pppiExcitation;
+ Word32 ***pppiAlloc;
+
+ Word32 iAllocOffset;
+
+ Word32 ***pppiLCLDSignReal;
+ Word32 ***pppiLCLDSignImag;
+ Word32 ***pppiQLCLDReal;
+ Word32 ***pppiQLCLDImag;
+
+
+ PredictionEncoder *psPredictionEncoder;
+};
+/*------------------------------------------------------------------------------------------*
+ * Function Quantize()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+static Word32 Quantize_fx(
+ const Word32 fVal_fx,
+ const Word32 fScale_fx,
+ Word32 *iSign,
+ const Word32 iMaxVal )
+{
+ Word32 iVal_fx;
+ IF( GT_32( fVal_fx, 0 ) )
+ {
+ iVal_fx = (Word32) L_add( Mpy_32_32( fScale_fx, fVal_fx ), ONE_IN_Q20 );
+ *iSign = 0;
+ }
+ ELSE
+ {
+ iVal_fx = (Word32) L_add( Mpy_32_32( -fScale_fx, fVal_fx ), ONE_IN_Q20 );
+ *iSign = 1;
+ }
+ iVal_fx = ( iVal_fx < iMaxVal ) ? iVal_fx : iMaxVal;
+
+ return iVal_fx;
+}
+/*------------------------------------------------------------------------------------------*
+ * Function UnQuantize()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+static Word32 UnQuantize_fx(
+ const Word32 iVal_fx,
+ const Word32 fScale_fx,
+ const Word32 iSign )
+{
+
+ Word32 fVal_fx;
+ IF( EQ_32( iSign, 0 ) )
+ {
+ fVal_fx = Mpy_32_32( fScale_fx, iVal_fx ); // Q19
+ }
+ ELSE
+ {
+ fVal_fx = Mpy_32_32( -fScale_fx, iVal_fx ); // Q19
+ }
+ return fVal_fx;
+}
+static void PackReal(
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ Word32 ***pppfReal,
+ Word32 ***pppfImag )
+{
+ Word32 ch, b, n;
+ FOR( ch = 0; ch < iChannels; ch++ )
+ {
+ FOR( b = 0; b < LCLD_BANDS; b++ )
+ {
+ Word32 iRealBlock = 0;
+ move32();
+ FOR( n = 0; n < iNumBlocks; n += 2 )
+ {
+ pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b];
+ move32();
+ pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b];
+ move32();
+ iRealBlock++;
+ }
+ }
+ }
+}
+/*------------------------------------------------------------------------------------------*
+ * Function CreateLCLDEncoder()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+ivas_error CreateLCLDEncoder(
+ LCLDEncoder **psLCLDEncoder_out,
+ const Word32 iSampleRate,
+ const Word32 iChannels,
+ const Word32 iTargetBitRate,
+ const Word32 iAllowSidePred,
+ const Word16 iNumBlocks,
+ const Word16 iNumSubSets,
+ const Word32 iRealOnlyOut )
+{
+ Word32 n;
+ LCLDEncoder *psLCLDEncoder;
+ ivas_error error;
+ Word32 iMaxNumPredBands = 0;
+ move32();
+
+ assert( iSampleRate == 48000 ); // Fix
+ assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 );
+ assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS );
+
+ IF( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ psLCLDEncoder->iSampleRate = iSampleRate;
+ move32();
+ psLCLDEncoder->iChannels = iChannels;
+ move32();
+ psLCLDEncoder->iRealOnlyOut = iRealOnlyOut;
+ move32();
+ psLCLDEncoder->iAllocOffset = 0;
+ move32();
+
+ psLCLDEncoder->iTargetBitRate = iTargetBitRate;
+ move32();
+
+ psLCLDEncoder->piBandwidths = c_aiBandwidths48;
+ psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */
+ move32();
+ iMaxNumPredBands = L_min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 );
+ IF( EQ_32( iRealOnlyOut, 1 ) )
+ {
+ iMaxNumPredBands = 0;
+ move32();
+ assert( iNumSubSets == 1 );
+ psLCLDEncoder->iNumBlocks = L_deposit_l( shr( iNumBlocks, 1 ) );
+ }
+ ELSE
+ {
+ psLCLDEncoder->iNumBlocks = iNumBlocks;
+ move32();
+ }
+
+ psLCLDEncoder->iMSMode = 0;
+ move32();
+ IF( ( psLCLDEncoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ FOR( n = 0; n < MAX_BANDS; n++ )
+ {
+ psLCLDEncoder->piLRPhaseDiffs[n] = 0;
+ move32();
+ psLCLDEncoder->piMSPredCoefs[n] = 0;
+ move32();
+ }
+ psLCLDEncoder->iAllowSidePred = iAllowSidePred;
+ move32();
+
+ psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks );
+
+ psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */
+ move32();
+ IF( ( psLCLDEncoder->piNumGroups = (Word32 *) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->ppiGroupLengths = (Word32 **) malloc( psLCLDEncoder->iChannels * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiSMR = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiExcitation = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiAlloc = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+
+ IF( ( psLCLDEncoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ Word32 k;
+ IF( ( psLCLDEncoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+
+ IF( ( psLCLDEncoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ IF( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+
+ IF( ( psLCLDEncoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ IF( ( psLCLDEncoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ }
+ }
+
+ IF( ( error = CreatePredictionEncoder_fx( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, L_deposit_l( iNumSubSets ), iMaxNumPredBands ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ *psLCLDEncoder_out = psLCLDEncoder;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*------------------------------------------------------------------------------------------*
+ * Function DeleteLCLDEncoder()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+void DeleteLCLDEncoder(
+ LCLDEncoder *psLCLDEncoder )
+{
+ Word32 k, n;
+
+ IF( psLCLDEncoder != NULL )
+ {
+
+ IF( psLCLDEncoder->piMSFlags != NULL )
+ {
+ free( psLCLDEncoder->piMSFlags );
+ }
+
+ IF( psLCLDEncoder->piNumGroups != NULL )
+ {
+ free( psLCLDEncoder->piNumGroups );
+ }
+
+ IF( psLCLDEncoder->psRMSEnvelopeGrouping != NULL )
+ {
+ DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping );
+ }
+
+ IF( psLCLDEncoder->ppiGroupLengths != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ free( psLCLDEncoder->ppiGroupLengths[n] );
+ }
+ free( psLCLDEncoder->ppiGroupLengths );
+ }
+ IF( psLCLDEncoder->pppiRMSEnvelope != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiRMSEnvelope[n][k] );
+ }
+ free( psLCLDEncoder->pppiRMSEnvelope[n] );
+ }
+ free( psLCLDEncoder->pppiRMSEnvelope );
+ }
+
+ IF( psLCLDEncoder->pppiSMR != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiSMR[n][k] );
+ }
+ free( psLCLDEncoder->pppiSMR[n] );
+ }
+ free( psLCLDEncoder->pppiSMR );
+ }
+
+ IF( psLCLDEncoder->pppiExcitation != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiExcitation[n][k] );
+ }
+ free( psLCLDEncoder->pppiExcitation[n] );
+ }
+ free( psLCLDEncoder->pppiExcitation );
+ }
+
+ IF( psLCLDEncoder->pppiAlloc != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiAlloc[n][k] );
+ }
+ free( psLCLDEncoder->pppiAlloc[n] );
+ }
+ free( psLCLDEncoder->pppiAlloc );
+ }
+
+ IF( psLCLDEncoder->pppiLCLDSignReal != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiLCLDSignReal[n][k] );
+ }
+ free( psLCLDEncoder->pppiLCLDSignReal[n] );
+ }
+ free( psLCLDEncoder->pppiLCLDSignReal );
+ }
+
+ IF( psLCLDEncoder->pppiLCLDSignImag != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiLCLDSignImag[n][k] );
+ }
+ free( psLCLDEncoder->pppiLCLDSignImag[n] );
+ }
+ free( psLCLDEncoder->pppiLCLDSignImag );
+ }
+
+ IF( psLCLDEncoder->pppiQLCLDReal != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiQLCLDReal[n][k] );
+ }
+ free( psLCLDEncoder->pppiQLCLDReal[n] );
+ }
+ free( psLCLDEncoder->pppiQLCLDReal );
+ }
+
+ IF( psLCLDEncoder->pppiQLCLDImag != NULL )
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ )
+ {
+ free( psLCLDEncoder->pppiQLCLDImag[n][k] );
+ }
+ free( psLCLDEncoder->pppiQLCLDImag[n] );
+ }
+ free( psLCLDEncoder->pppiQLCLDImag );
+ }
+
+ DeletePredictionEncoder_fx( psLCLDEncoder->psPredictionEncoder );
+ free( psLCLDEncoder );
+ }
+
+ return;
+}
+
+/*------------------------------------------------------------------------------------------*
+ * Local function declarations
+ *------------------------------------------------------------------------------------------*/
+
+static Word32 MSModeCalculation_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 Q_in, Word32 *piMSMode, Word32 *piLRPhaseDiff, Word32 *piMSPredCoef, const Word32 iAllowSidePred, const Word32 iRealOnlyOut, Word32 *piMSFlags );
+static void RemoveRMSEnvelope( const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iNumGroups, const Word32 *piGroupLengths, Word32 **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx );
+static Word32 CountLCLDBits( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 *piPredEnable, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag );
+
+static Word32 WriteHeaderInformation( const Word32 iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 WriteMSInformation( const Word32 iNumBands, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiff, const Word32 *piMSPredCoef, Word32 iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 WriteGroupInformation( const Word32 iChannels, const Word32 iCommonGrouping, const Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 WriteRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 WriteAllocInformation( const Word32 iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+static Word32 WriteLCLDData( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits );
+static Word32 ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 q_final, Word32 ***pppiSMR, const Word32 iAvailableBits, Word32 *piAllocOffset, Word32 ***pppiAlloc, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 ***pppiSignReal, Word32 ***pppiSignImag, PredictionEncoder *psPredictionEncoder );
+/*------------------------------------------------------------------------------------------*
+ * Function EncodeLCLDFrame()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+Word32 EncodeLCLDFrame(
+ LCLDEncoder *psLCLDEncoder,
+ Word32 ***pppfLCLDReal_fx,
+ Word32 ***pppfLCLDImag_fx,
+ Word32 *piBitsWritten,
+ const Word32 available_bits,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word16 *q_final )
+{
+ Word32 n;
+ Word32 iAvailableBits, iBitsWritten;
+ Word32 iNumMSBands = 0;
+ Word32 iAudioBitsWritten;
+
+ iAvailableBits = available_bits; // HCBR for now
+ iBitsWritten = 0;
+ assert( available_bits <= pBits->buf_len * 8 );
+ IF( EQ_32( psLCLDEncoder->iRealOnlyOut, 1 ) )
+ {
+ PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal_fx, pppfLCLDImag_fx );
+ }
+ /* Do MS calc here */
+ IF( EQ_32( psLCLDEncoder->iChannels, 2 ) )
+ {
+ iNumMSBands = MSModeCalculation_fx( psLCLDEncoder->iNumBlocks,
+ psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piBandwidths,
+ pppfLCLDReal_fx,
+ pppfLCLDImag_fx,
+ *q_final,
+ &psLCLDEncoder->iMSMode,
+ psLCLDEncoder->piLRPhaseDiffs,
+ psLCLDEncoder->piMSPredCoefs,
+ psLCLDEncoder->iAllowSidePred,
+ psLCLDEncoder->iRealOnlyOut,
+ psLCLDEncoder->piMSFlags );
+ IF( GT_32( psLCLDEncoder->iMSMode, 0 ) )
+ {
+ psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use
+ }
+ }
+ /* Compute Grouping and RMS Envelopes */
+ IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) )
+ {
+ ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping,
+ psLCLDEncoder->iChannels,
+ psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piBandwidths,
+ pppfLCLDReal_fx,
+ pppfLCLDImag_fx,
+ &psLCLDEncoder->piNumGroups[0],
+ psLCLDEncoder->ppiGroupLengths[0],
+ psLCLDEncoder->pppiRMSEnvelope,
+ *q_final );
+ psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0];
+ FOR( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ )
+ {
+ psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n];
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping,
+ psLCLDEncoder->iChannels,
+ psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piBandwidths,
+ &pppfLCLDReal_fx[n],
+ &pppfLCLDImag_fx[n],
+ &psLCLDEncoder->piNumGroups[n],
+ psLCLDEncoder->ppiGroupLengths[n],
+ &psLCLDEncoder->pppiRMSEnvelope[n], *q_final );
+ }
+ }
+
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ RemoveRMSEnvelope( psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piBandwidths,
+ psLCLDEncoder->piNumGroups[n],
+ (const Word32 *) psLCLDEncoder->ppiGroupLengths[n],
+ psLCLDEncoder->pppiRMSEnvelope[n],
+ pppfLCLDReal_fx[n],
+ pppfLCLDImag_fx[n] );
+ }
+ *q_final = add( *q_final, 9 ); // Increasing the Q as it has changed inside the RemoveRMSEnvelope
+
+ ComputePredictors_fx( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal_fx, pppfLCLDImag_fx );
+
+ iBitsWritten = L_add( iBitsWritten, WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ) );
+
+ IF( EQ_32( psLCLDEncoder->iChannels, 2 ) )
+ {
+ iBitsWritten = L_add( iBitsWritten, WriteMSInformation( psLCLDEncoder->iNumBands,
+ psLCLDEncoder->iMSMode,
+ (const Word32 *) psLCLDEncoder->piMSFlags,
+ (const Word32 *) psLCLDEncoder->piLRPhaseDiffs,
+ (const Word32 *) psLCLDEncoder->piMSPredCoefs,
+ iNumMSBands,
+ pBits ) );
+ }
+
+
+ iBitsWritten = L_add( iBitsWritten, WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ) );
+
+ iBitsWritten = L_add( iBitsWritten, WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ) );
+
+ iBitsWritten = L_add( iBitsWritten, WriteRMSEnvelope( psLCLDEncoder->iChannels, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ) );
+
+
+ IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) )
+ {
+ Word32 k;
+ FOR( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ )
+ {
+ PerceptualModelStereo_fx( psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piMSFlags,
+ psLCLDEncoder->pppiRMSEnvelope[0][k],
+ psLCLDEncoder->pppiRMSEnvelope[1][k],
+ psLCLDEncoder->pppiExcitation[0][k],
+ psLCLDEncoder->pppiExcitation[1][k],
+ psLCLDEncoder->pppiSMR[0][k],
+ psLCLDEncoder->pppiSMR[1][k] );
+ }
+ }
+ ELSE
+ {
+ FOR( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ )
+ {
+ PerceptualModel_fx( psLCLDEncoder->iNumBands,
+ psLCLDEncoder->pppiRMSEnvelope[n][k],
+ psLCLDEncoder->pppiExcitation[n][k],
+ psLCLDEncoder->pppiSMR[n][k] );
+ }
+ }
+ }
+#ifdef DEBUG_WRITE_PREDICTORS
+ {
+ static FILE *fid;
+ if ( !fid )
+ fid = fopen( "pred_enc.txt", "wt" );
+ for ( n = 0; n < psLCLDEncoder->iChannels; n++ )
+ {
+ int16_t b;
+ for ( b = 0; b < 60; b++ )
+ fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] );
+ }
+ fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] );
+ }
+#endif
+ iAvailableBits = L_sub( iAvailableBits, iBitsWritten );
+
+ ComputeAllocation( psLCLDEncoder->iChannels,
+ (const Word32 *) psLCLDEncoder->piNumGroups,
+ psLCLDEncoder->ppiGroupLengths,
+ psLCLDEncoder->iNumBands,
+ psLCLDEncoder->piBandwidths,
+ pppfLCLDReal_fx,
+ pppfLCLDImag_fx,
+ *q_final,
+ psLCLDEncoder->pppiSMR,
+ iAvailableBits,
+ &psLCLDEncoder->iAllocOffset,
+ psLCLDEncoder->pppiAlloc,
+ psLCLDEncoder->pppiQLCLDReal,
+ psLCLDEncoder->pppiQLCLDImag,
+ psLCLDEncoder->pppiLCLDSignReal,
+ psLCLDEncoder->pppiLCLDSignImag,
+ psLCLDEncoder->psPredictionEncoder );
+
+ iBitsWritten = L_add( iBitsWritten, WriteAllocInformation( psLCLDEncoder->iAllocOffset,
+ pBits ) );
+ iAudioBitsWritten = iBitsWritten;
+ iBitsWritten = L_add( iBitsWritten, WriteLCLDData( psLCLDEncoder->piNumGroups,
+ psLCLDEncoder->ppiGroupLengths,
+ psLCLDEncoder->iNumBands,
+ psLCLDEncoder->iChannels,
+ psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable,
+ psLCLDEncoder->psPredictionEncoder->iNumSubSets,
+ psLCLDEncoder->psPredictionEncoder->iSubSetId,
+ psLCLDEncoder->pppiAlloc,
+ psLCLDEncoder->pppiLCLDSignReal,
+ psLCLDEncoder->pppiLCLDSignImag,
+ psLCLDEncoder->pppiQLCLDReal,
+ psLCLDEncoder->pppiQLCLDImag,
+ pBits ) );
+ *piBitsWritten = iBitsWritten;
+ move32();
+ iAudioBitsWritten = L_sub( iBitsWritten, iAudioBitsWritten );
+
+ UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder );
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------------------------*
+ * Function GetNumGroups()
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+Word32 GetNumGroups( LCLDEncoder *psLCLDEncoder )
+{
+ return psLCLDEncoder->piNumGroups[0];
+}
+
+
+/*------------------------------------------------------------------------------------------*
+ * Local functions
+ *
+ *
+ *------------------------------------------------------------------------------------------*/
+
+enum MSPred_Types
+{
+ MS_PHASE_AND_PRED = 0, /* LR phase alignment + real-valued M/S prediction */
+ MS_PRED_ONLY = 1, /* real-valued M/S prediction */
+ MS_PHASE_ONLY = 2 /* LR phase alignment + M/S */
+};
+
+enum MS_BS_TYPES
+{
+ MS_OFF = 0,
+ MS_ALL = 1,
+ MS_SOME = 2,
+ MS_PRED = 3
+};
+static Word32 MSModeCalculation_fx(
+ const Word32 iNumBlocks,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ /*float ***pppfReal,
+ float ***pppfImag,*/
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx,
+ Word16 Q_in,
+ Word32 *piMSMode,
+ Word32 *piLRPhaseDiffs,
+ Word32 *piMSPredCoefs,
+ const Word32 iAllowSidePred,
+ const Word32 iRealOnlyOut,
+ Word32 *piMSFlags )
+{
+ Word32 b;
+ Word32 iFBOffset;
+ Word32 iNumMSBands;
+ Word32 iMSPredType;
+ /*float fMSBitGain = 0.0f;
+ float pfMSPredBitGain[3] = { 0.0f };
+ float fPred;*/
+ Word32 fMSBitGain_fx = 0;
+ Word32 pfMSPredBitGain_fx[3] = { 0 };
+ Word32 fPred_fx;
+ Word32 piMSPredFlags0[MAX_BANDS] = { 0 };
+ Word32 piMSPredFlags1[MAX_BANDS] = { 0 };
+ Word32 piMSPredFlags2[MAX_BANDS] = { 0 };
+ Word32 *ppiMSPredFlags[3];
+ Word32 piMSPredCoefs0[MAX_BANDS] = { 0 };
+ Word32 piMSPredCoefs1[MAX_BANDS] = { 0 };
+ Word32 piMSPredCoefs2[MAX_BANDS] = { 0 };
+ Word32 *ppiMSPredCoefs[3];
+ Word32 piMSPredPhase0[MAX_BANDS] = { 0 };
+ Word32 piMSPredPhase1[MAX_BANDS] = { 0 };
+ Word32 piMSPredPhase2[MAX_BANDS] = { 0 };
+ Word32 *ppiMSPredPhase[3];
+ Word32 iMsInfoBits;
+ Word32 piMsPredInfoBits[3] = { 0 };
+
+ // const float feps = 1e-12f;
+ // float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */
+ const Word32 feps_fx = 1; // is this correct?
+ move32();
+ Word32 fBitsFactor_fx = 1783446565; /* = 1/log10(2) (Q29), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */
+ move32();
+ IF( LT_32( iNumBlocks, LCLD_BLOCKS_PER_FRAME ) )
+ {
+ // fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */
+ fBitsFactor_fx = Mpy_32_32( fBitsFactor_fx, L_add( 1503238553, W_extract_l( W_mult0_32_32( L_sub( iNumBlocks, 4 ), 596523235 ) ) ) ); /* Tuning for relatively higher side rate due to shorter frame length */
+ }
+
+ ppiMSPredFlags[0] = piMSPredFlags0;
+ move32();
+ ppiMSPredFlags[1] = piMSPredFlags1;
+ move32();
+ ppiMSPredFlags[2] = piMSPredFlags2;
+ move32();
+ ppiMSPredCoefs[0] = piMSPredCoefs0;
+ move32();
+ ppiMSPredCoefs[1] = piMSPredCoefs1;
+ move32();
+ ppiMSPredCoefs[2] = piMSPredCoefs2;
+ move32();
+ ppiMSPredPhase[0] = piMSPredPhase0;
+ move32();
+ ppiMSPredPhase[1] = piMSPredPhase1;
+ move32();
+ ppiMSPredPhase[2] = piMSPredPhase2;
+ move32();
+ *piMSMode = MS_OFF;
+ move32();
+ iFBOffset = 0;
+ move32();
+ iNumMSBands = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 n;
+ /*float fLeftEnergy;
+ float fRightEnergy;
+ float fMidEnergy;
+ float fSideEnergy;
+ float fLRRatio;
+ float fMSRatio;
+ float pfMSPredRatio[3] = { 0.0f };
+ float fMidEnergyPred;
+ float fSideEnergyPred;
+ float fLRCovReal = 0.0f;
+ float fLRCovImag = 0.0f;*/
+ Word32 fLeftEnergy_fx;
+ Word32 fRightEnergy_fx;
+ Word32 fMidEnergy_fx;
+ Word32 fSideEnergy_fx;
+ Word64 fLeftEnergy_fx64;
+ Word64 fRightEnergy_fx64;
+ Word64 fMidEnergy_fx64;
+ Word64 fSideEnergy_fx64;
+ Word32 fLRRatio_fx;
+ Word32 fMSRatio_fx;
+ Word32 pfMSPredRatio_fx[3] = { 0 };
+ Word32 fMidEnergyPred_fx;
+ Word32 fSideEnergyPred_fx;
+ Word32 fLRCovReal_fx = 0;
+ Word32 fLRCovImag_fx = 0;
+ Word64 fLRCovReal_fx64 = 0;
+ Word64 fLRCovImag_fx64 = 0;
+ Word32 iPhase;
+ Word32 iPred;
+ Word32 tabIdx = 0;
+ // float fNumLines = (float)(iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2); /* per band per channel */
+ // float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */
+ Word32 fNumLines_fx = iRealOnlyOut == 1 ? L_shl( iNumBlocks * piBandwidths[b], 2 ) : L_shl( iNumBlocks * piBandwidths[b], 1 ); /* per band per channel */
+ Word32 fLevelToSMRdBFactor_fx = L_shl( c_aiDefaultTheta48[b], 23 ); /* frequency dependent SMR slope in psy model Q23:sub(Q31, PERCEPTUAL_MODEL_SLGAIN_SHIFT) */
+ fLeftEnergy_fx = 0;
+ fRightEnergy_fx = 0;
+ fMidEnergy_fx = 0;
+ fSideEnergy_fx = 0;
+ fLeftEnergy_fx64 = 0;
+ fRightEnergy_fx64 = 0;
+ fMidEnergy_fx64 = 0;
+ fSideEnergy_fx64 = 0;
+ Word16 Q_en_tmp = 63;
+
+ FOR( n = 0; n < piBandwidths[b]; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < iNumBlocks; k++ )
+ {
+ /*float fMidReal;
+ float fMidImag;
+ float fSideReal;
+ float fSideImag;*/
+ Word32 fMidReal_fx;
+ Word32 fMidImag_fx;
+ Word32 fSideReal_fx;
+ Word32 fSideImag_fx;
+
+ // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] );
+ fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
+ // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] );
+ fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
+ // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] );
+ fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
+ // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] );
+ fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
+
+ // fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] );
+ fLeftEnergy_fx64 = W_add( fLeftEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[0][k][iFBOffset] ) ) );
+ // fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] );
+ fRightEnergy_fx64 = W_add( fRightEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[1][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) );
+ // fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag );
+ fMidEnergy_fx64 = W_add( fMidEnergy_fx64, W_add( W_mult0_32_32( fMidReal_fx, fMidReal_fx ), W_mult0_32_32( fMidImag_fx, fMidImag_fx ) ) );
+ // fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag );
+ fSideEnergy_fx64 = W_add( fSideEnergy_fx64, W_add( W_mult0_32_32( fSideReal_fx, fSideReal_fx ), W_mult0_32_32( fSideImag_fx, fSideImag_fx ) ) );
+
+ // fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] );
+ fLRCovReal_fx64 = W_add( fLRCovReal_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) );
+ // fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] );
+ fLRCovImag_fx64 = W_add( fLRCovImag_fx64, W_sub( W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ) ) );
+ }
+
+ iFBOffset++;
+ }
+ Q_en_tmp = min( Q_en_tmp, W_norm( fLeftEnergy_fx64 ) );
+ Q_en_tmp = min( Q_en_tmp, W_norm( fRightEnergy_fx64 ) );
+ Q_en_tmp = min( Q_en_tmp, W_norm( fMidEnergy_fx64 ) );
+ Q_en_tmp = min( Q_en_tmp, W_norm( fSideEnergy_fx64 ) );
+ Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovReal_fx64 ) );
+ Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovImag_fx64 ) );
+ Q_en_tmp = sub( Q_en_tmp, 2 );
+ fLeftEnergy_fx = W_extract_h( W_shl( fLeftEnergy_fx64, Q_en_tmp ) );
+ fRightEnergy_fx = W_extract_h( W_shl( fRightEnergy_fx64, Q_en_tmp ) );
+ fMidEnergy_fx = W_extract_h( W_shl( fMidEnergy_fx64, Q_en_tmp ) );
+ fSideEnergy_fx = W_extract_h( W_shl( fSideEnergy_fx64, Q_en_tmp ) );
+ fLRCovReal_fx = W_extract_h( W_shl( fLRCovReal_fx64, Q_en_tmp ) );
+ fLRCovImag_fx = W_extract_h( W_shl( fLRCovImag_fx64, Q_en_tmp ) );
+ Word16 Q_en = add( shl( Q_in, 1 ), sub( Q_en_tmp, 32 ) ) /*2 * Q_in - 31 - 2*/;
+ /* M/S prediction without phase alignment*/
+ // fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps );
+ // iPred = quantPred(fPred);
+ // fPred = dequantPred(iPred);
+ Word16 exp;
+ fPred_fx = BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), L_add( fMidEnergy_fx, feps_fx ), &exp );
+ exp = sub( exp, 2 ); //*0.25f
+ fPred_fx = L_shl( fPred_fx, 16 );
+ iPred = quantPred_fx( fPred_fx, exp );
+ fPred_fx = dequantPred_fx( iPred ); // Q31
+ // fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) );
+ fSideEnergyPred_fx = L_add( fSideEnergy_fx,
+ L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergy_fx ),
+ L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) );
+ fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 );
+
+ ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred;
+ move32();
+ ppiMSPredPhase[MS_PRED_ONLY][b] = 0;
+ move32();
+ // pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) );
+ pfMSPredRatio_fx[MS_PRED_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
+ // printf("%f ", (float)pfMSPredRatio_fx[MS_PRED_ONLY] / (1 << 25));
+
+ /* Phase alignment*/
+ iPhase = 0;
+ move32();
+ // if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy )
+ IF( GT_32( L_add( Mpy_32_32( fLRCovReal_fx, fLRCovReal_fx ), Mpy_32_32( fLRCovImag_fx, fLRCovImag_fx ) ), L_shr( Mpy_32_32( fLeftEnergy_fx, fRightEnergy_fx ), 1 ) ) )
+ {
+ // float fPhase = atan2f( fLRCovImag, fLRCovReal );
+ Word32 fPhase_fx = BASOP_util_atan2( fLRCovImag_fx, fLRCovReal_fx, 0 );
+ exp = sub( 18, norm_l( fPhase_fx ) );
+ fPhase_fx = L_shl( fPhase_fx, norm_l( fPhase_fx ) ); // Q31
+ // iPhase = quantPhase( fPhase );
+ iPhase = quantPhase_fx( fPhase_fx, exp );
+ }
+
+ /* adjust covariance */
+ tabIdx = L_sub( iPhase, PHASE_MIN_VAL );
+ // cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] );
+ cplxmult_fx( &fLRCovReal_fx, &fLRCovImag_fx, c_afRotRealImag_fx[tabIdx][0], -c_afRotRealImag_fx[tabIdx][1] );
+
+ /* compute MS prediction coefficient based on adjusted covariance */
+ // fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal );
+ fMidEnergyPred_fx = L_add( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en
+ // fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal );
+ fSideEnergyPred_fx = L_sub( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en
+ fSideEnergyPred_fx = L_max( fSideEnergyPred_fx, 0 );
+
+ /* M/S with LR phase alignment but without prediction */
+ ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0;
+ move32();
+ ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase;
+ move32();
+ // pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) );
+ pfMSPredRatio_fx[MS_PHASE_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
+ // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_ONLY] / (1 << 25));
+
+ /* M/S with LR phase alignment and prediction */
+ // fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred;
+ fPred_fx = fMidEnergyPred_fx == 0 ? 0 : BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), fMidEnergyPred_fx, &exp );
+ exp = sub( exp, 2 ); //*0.25f
+ fPred_fx = L_shl( fPred_fx, 16 );
+ // iPred = quantPred( fPred );
+ iPred = quantPred_fx( fPred_fx, exp );
+ // fPred = dequantPred( iPred );
+ fPred_fx = dequantPred_fx( iPred );
+ // fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) );
+ fSideEnergyPred_fx = L_add( fSideEnergyPred_fx,
+ L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergyPred_fx ),
+ L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) );
+ fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 );
+ /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */
+ ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred;
+ move32();
+ ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase;
+ move32();
+ // pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) );
+ pfMSPredRatio_fx[MS_PHASE_AND_PRED] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25
+ // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_AND_PRED] / (1 << 25));
+
+ /* Plain M/S */
+ // fLeftEnergy = log10f( fLeftEnergy + feps );
+ exp = sub( 31, Q_en ); // 31 - Q
+ fLeftEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fLeftEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
+ // fRightEnergy = log10f( fRightEnergy + feps );
+ fRightEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fRightEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
+ // fMidEnergy = log10f( fMidEnergy + feps );
+ fMidEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
+ // fSideEnergy = log10f( fSideEnergy + feps );
+ fSideEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fSideEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25
+
+ // fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy );
+ fLRRatio_fx = ( fLeftEnergy_fx > fRightEnergy_fx ? L_sub( fLeftEnergy_fx, fRightEnergy_fx ) : L_sub( fRightEnergy_fx, fLeftEnergy_fx ) ); // Q25
+ // fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy );
+ fMSRatio_fx = ( fMidEnergy_fx > fSideEnergy_fx ? L_sub( fMidEnergy_fx, fSideEnergy_fx ) : L_sub( fSideEnergy_fx, fMidEnergy_fx ) ); // Q25
+
+ // if ( fMSRatio > fLRRatio )
+ IF( GT_32( fMSRatio_fx, fLRRatio_fx ) )
+ {
+ iNumMSBands++;
+ piMSFlags[b] = 1;
+ move32();
+ // fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor;
+ fMSBitGain_fx = L_add( fMSBitGain_fx, W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, Mpy_32_32( Mpy_32_32( L_sub( fMSRatio_fx, fLRRatio_fx ), fLevelToSMRdBFactor_fx ), fBitsFactor_fx ) ), 7 ) ) ); // Q16
+ }
+ ELSE
+ {
+ piMSFlags[b] = 0;
+ move32();
+ }
+ piLRPhaseDiffs[b] = 0;
+ move32();
+ piMSPredCoefs[b] = 0;
+ move32();
+
+ /* MSPred bit gains based on increase of level ratio compared to L/R ratio and the level dependent psy-model */
+ FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ )
+ {
+ // if ( pfMSPredRatio[iMSPredType] > fLRRatio )
+ IF( GT_32( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ) )
+ {
+ ppiMSPredFlags[iMSPredType][b] = 1;
+ move32();
+ // pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor;
+ pfMSPredBitGain_fx[iMSPredType] = L_add( pfMSPredBitGain_fx[iMSPredType],
+ W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx,
+ Mpy_32_32( Mpy_32_32( L_sub( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ), fLevelToSMRdBFactor_fx ),
+ fBitsFactor_fx ) ),
+ 7 ) ) ); // Q16
+ }
+ }
+ }
+ Word16 q_fMSBitGain_fx = Q16;
+ move16();
+ Word16 q_pfMSPredBitGain_fx = Q16; // Q23-7
+ move16();
+ /* remove signalling cost from bit gains */
+ FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ )
+ {
+ piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] );
+ // pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f );
+ pfMSPredBitGain_fx[iMSPredType] = max( pfMSPredBitGain_fx[iMSPredType] - L_shl( piMsPredInfoBits[iMSPredType], q_pfMSPredBitGain_fx ), 0 );
+ }
+
+ /* find the best M/S Pred type */
+ IF( EQ_32( iRealOnlyOut, 1 ) )
+ {
+ iMSPredType = MS_PRED_ONLY;
+ move32();
+ }
+ ELSE
+ {
+ iMSPredType = MS_PHASE_AND_PRED;
+ move32();
+ // iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType );
+ iMSPredType = ( pfMSPredBitGain_fx[MS_PRED_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PRED_ONLY : iMSPredType );
+ // iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType );
+ iMSPredType = ( pfMSPredBitGain_fx[MS_PHASE_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PHASE_ONLY : iMSPredType );
+ }
+
+ /* plain M/S */
+ iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL );
+ // fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f );
+ fMSBitGain_fx = L_max( L_sub( fMSBitGain_fx, L_shl( iMsInfoBits, q_fMSBitGain_fx ) ), 0 ); // Q_en -2
+ // if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain )
+ test();
+ IF( iAllowSidePred && GT_32( L_shr_r( pfMSPredBitGain_fx[iMSPredType], sub( q_pfMSPredBitGain_fx, q_fMSBitGain_fx ) ), L_add( fMSBitGain_fx, Mpy_32_32( fMSBitGain_fx, 214748364 ) ) ) )
+ {
+ *piMSMode = MS_PRED;
+ move32();
+ iNumMSBands = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ piMSFlags[b] = ppiMSPredFlags[iMSPredType][b];
+ IF( EQ_32( piMSFlags[b], 1 ) )
+ {
+ piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b];
+ move32();
+ piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b];
+ move32();
+ iNumMSBands++;
+ }
+ ELSE
+ {
+ piMSPredCoefs[b] = 0;
+ move32();
+ piLRPhaseDiffs[b] = 0;
+ move32();
+ }
+ }
+ }
+ ELSE IF( EQ_32( iNumMSBands, iNumBands ) )
+ {
+ *piMSMode = MS_ALL;
+ move32();
+ }
+ ELSE IF( GT_32( iNumMSBands, 0 ) )
+ {
+ *piMSMode = MS_SOME;
+ move32();
+ }
+ ELSE
+ {
+ *piMSMode = MS_OFF;
+ move32();
+ }
+#ifdef DEBUG_WRITE_MS_PRED
+ {
+ static FILE *fid;
+ int32_t iActualInfoBits = CountMSBits( iNumBands, *piMSMode, piMSFlags, piLRPhaseDiffs, piMSPredCoefs );
+ if ( !fid )
+ fid = fopen( "ms_info_bits.txt", "wt" );
+ fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits );
+ }
+#endif
+ IF( NE_32( *piMSMode, MS_OFF ) )
+ {
+ iFBOffset = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ IF( EQ_32( piMSFlags[b], 1 ) )
+ {
+ Word32 n;
+ Word32 phaseIdx;
+ phaseIdx = L_sub( piLRPhaseDiffs[b], PHASE_MIN_VAL );
+ // fPred = dequantPred( piMSPredCoefs[b] );
+ fPred_fx = dequantPred_fx( piMSPredCoefs[b] ); // Q31
+ FOR( n = 0; n < piBandwidths[b]; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < iNumBlocks; k++ )
+ {
+ /*float fMidReal;
+ float fMidImag;
+ float fSideReal;
+ float fSideImag;*/
+ Word32 fMidReal_fx;
+ Word32 fMidImag_fx;
+ Word32 fSideReal_fx;
+ Word32 fSideImag_fx;
+
+ IF( EQ_32( *piMSMode, MS_PRED ) )
+ {
+ // cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] );
+ cplxmult_fx( &pppfReal_fx[1][k][iFBOffset], &pppfImag_fx[1][k][iFBOffset], c_afRotRealImag_fx[phaseIdx][0], c_afRotRealImag_fx[phaseIdx][1] );
+ }
+
+ // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] );
+ fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
+ // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] );
+ fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
+ // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] );
+ fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 );
+ // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] );
+ fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 );
+
+ IF( EQ_32( *piMSMode, MS_PRED ) )
+ {
+ // fSideReal -= fPred * fMidReal;
+ fSideReal_fx = L_sub( fSideReal_fx, Mpy_32_32( fPred_fx, fMidReal_fx ) );
+ // fSideImag -= fPred * fMidImag;
+ fSideImag_fx = L_sub( fSideImag_fx, Mpy_32_32( fPred_fx, fMidImag_fx ) );
+ }
+
+ pppfReal_fx[0][k][iFBOffset] = fMidReal_fx;
+ move32();
+ pppfReal_fx[1][k][iFBOffset] = fSideReal_fx;
+ move32();
+ pppfImag_fx[0][k][iFBOffset] = fMidImag_fx;
+ move32();
+ pppfImag_fx[1][k][iFBOffset] = fSideImag_fx;
+ move32();
+ }
+ iFBOffset++;
+ }
+ }
+ ELSE
+ {
+ iFBOffset = L_add( iFBOffset, piBandwidths[b] );
+ }
+ }
+ }
+#ifdef DEBUG_WRITE_MS_PRED
+ {
+ static FILE *fid;
+ if ( !fid )
+ fid = fopen( "ms_enc.txt", "wt" );
+ writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags );
+ }
+#endif
+ IF( EQ_32( *piMSMode, MS_PRED ) )
+ {
+ /* Differential Coding of Phase Data*/
+ PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands );
+ PrepEncode( piMSPredCoefs, piMSFlags, iNumBands );
+#ifdef DEBUG_WRITE_MS_PRED
+ {
+ static FILE *fid;
+ if ( !fid )
+ fid = fopen( "ms_pred_enc.txt", "wt" );
+ writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags );
+ }
+#endif
+ /* Differential Coding*/
+ EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM );
+ EncodePredCoef( piMSPredCoefs, iNumMSBands );
+ }
+
+ return iNumMSBands;
+}
+static void RemoveRMSEnvelope(
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ Word32 **ppiRMSEnvelope,
+ Word32 **ppfReal_fx,
+ Word32 **ppfImag_fx )
+{
+ Word32 k, n, b, iFBOffset, m, iRMSEnv;
+ Word32 iBlockOffset;
+ Word32 fGain_fx;
+ Word16 fGain_exp;
+ iBlockOffset = 0;
+ move32();
+ Word64 tmp;
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ iFBOffset = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ iRMSEnv = ppiRMSEnvelope[n][b];
+ IF( EQ_32( L_add( ENV_RECONSTRUCT_TABLE_CENTER, iRMSEnv ) % 2, 0 ) )
+ {
+ fGain_fx = 1073741824; // 2 ^ 30
+ move32();
+ }
+ ELSE
+ {
+ fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30
+ move32();
+ }
+ fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv];
+ move16();
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] );
+ tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9)
+ ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
+ move32();
+ tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] );
+ tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9)
+ ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp );
+ move32();
+ iFBOffset++;
+ }
+ }
+ iBlockOffset++;
+ }
+ }
+
+ return;
+}
+static void QuantizeSpectrumDPCM_Opt(
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 **ppiAlloc,
+ Word32 **ppfReal_fx,
+ Word32 **ppfImag_fx,
+ Word16 q_final,
+ Word32 **ppiQReal,
+ Word32 **ppiQImag,
+ Word32 **ppiSignReal,
+ Word32 **ppiSignImag,
+ Word32 iNumSubSets,
+ Word32 iSubSetId,
+ Word32 *piPredEnable,
+ Word32 *pfA1Real_fx,
+ Word32 *pfA1Imag_fx,
+ Word32 *pfPredStateReal_fx,
+ Word32 *pfPredStateImag_fx )
+{
+ Word32 b, n;
+ Word32 iFBOffset;
+ Word32 k, iAlloc;
+ Word32 iMaxQuantVal_fx;
+ Word32 fSCFGain_fx, fInvSCFGain_fx;
+ iFBOffset = 0;
+ Word32 ppiQReal_fx, ppiQImag_fx;
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 m;
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ Word32 iBlockOffset = 0;
+ IF( EQ_32( piPredEnable[iFBOffset], 1 ) )
+ {
+ Word32 fReal_fx;
+ Word32 fImag_fx;
+ Word32 iSubset = iFBOffset % iNumSubSets;
+ Word32 fPrevReal_fx = 0;
+ Word32 fPrevImag_fx = 0;
+ IF( NE_32( iSubset, iSubSetId ) )
+ {
+ /* run predictors across sub-frames */
+ fPrevReal_fx = pfPredStateReal_fx[iFBOffset];
+ move32();
+ fPrevImag_fx = pfPredStateImag_fx[iFBOffset];
+ move32();
+ }
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ iAlloc = ppiAlloc[n][b];
+ iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc];
+ fSCFGain_fx = c_afScaleFactor_fx[iAlloc];
+ fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc];
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ /* prediction */
+ fReal_fx = L_sub( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevReal_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevImag_fx ) );
+ fImag_fx = L_add( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevImag_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevReal_fx ) );
+ ppiQReal_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fReal_fx ), /* quantize residual */
+ fSCFGain_fx,
+ &ppiSignReal[iBlockOffset][iFBOffset],
+ iMaxQuantVal_fx );
+ ppiQImag_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fImag_fx ),
+ fSCFGain_fx,
+ &ppiSignImag[iBlockOffset][iFBOffset],
+ iMaxQuantVal_fx );
+ ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 );
+
+ ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 );
+
+ ppiQReal_fx = L_shl( ppiQReal[iBlockOffset][iFBOffset], 21 );
+ fPrevReal_fx = L_sub( L_shl( UnQuantize_fx( ppiQReal_fx,
+ fInvSCFGain_fx,
+ ppiSignReal[iBlockOffset][iFBOffset] ),
+ 9 ),
+ fReal_fx );
+ /* add prediction to quantized residual = reconstructed sample */
+
+ ppiQImag_fx = L_shl( ppiQImag[iBlockOffset][iFBOffset], 21 );
+ fPrevImag_fx = L_sub( L_shl( UnQuantize_fx( ppiQImag_fx,
+ fInvSCFGain_fx,
+ ppiSignImag[iBlockOffset][iFBOffset] ),
+ 9 ),
+ fImag_fx );
+ iBlockOffset++;
+ } /* group length */
+ } /* groups */
+ pfPredStateReal_fx[iFBOffset] = fPrevReal_fx;
+ move32();
+ pfPredStateImag_fx[iFBOffset] = fPrevImag_fx;
+ move32();
+ } /* predEnable */
+ ELSE
+ { /* no prediction */
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ iAlloc = ppiAlloc[n][b];
+ move32();
+ iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc];
+ move32();
+ fSCFGain_fx = c_afScaleFactor_fx[iAlloc];
+ move32();
+ fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc];
+ move32();
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ ppiQReal_fx = Quantize_fx( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ),
+ fSCFGain_fx,
+ &ppiSignReal[iBlockOffset][iFBOffset],
+ iMaxQuantVal_fx );
+ ppiQImag_fx = Quantize_fx( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ),
+ fSCFGain_fx,
+ &ppiSignImag[iBlockOffset][iFBOffset],
+ iMaxQuantVal_fx );
+
+ ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 );
+
+ ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 );
+
+ iBlockOffset++;
+ } /* group length */
+ } /* groups */
+ } /* predEnable */
+ iFBOffset++;
+ } /* bandwidth */
+ }
+}
+static Word32 CountLCLDBits(
+ const Word32 iNumGroups,
+ const Word32 *piGroupLengths,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ const Word32 *piPredEnable,
+ Word32 **ppiAlloc,
+ Word32 **ppiQReal,
+ Word32 **ppiQImag )
+{
+ Word32 k, n, b, iFBOffset;
+ Word32 iBits, iBlockOffest;
+ Word32 m, iAlloc, iHuffDim, iHuffMod;
+
+ iBits = 0;
+ move32();
+ iBlockOffest = 0;
+ move32();
+ FOR( n = 0; n < iNumGroups; n++ )
+ {
+ FOR( k = 0; k < piGroupLengths[n]; k++ )
+ {
+ iFBOffset = 0;
+ move32();
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ iAlloc = ppiAlloc[n][b];
+ move32();
+
+ iHuffDim = c_aiHuffmanDim[iAlloc];
+ move32();
+ iHuffMod = c_aiHuffmanMod[iAlloc];
+ move32();
+
+ IF( GT_32( iAlloc, 0 ) )
+ {
+ const UWord16( *pauiHuffmanTable )[2] = NULL;
+ const UWord16( *pauiHuffmanTableDPCM )[2] = NULL;
+ pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
+ pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
+ FOR( m = 0; m < piBandwidths[b]; m++ )
+ {
+ Word32 iQuantValue1;
+ Word32 iQuantValue2;
+
+ iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset];
+ move32();
+ iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset];
+ move32();
+
+ iBits = L_add( iBits, GT_32( iQuantValue1, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */
+ iBits = L_add( iBits, GT_32( iQuantValue2, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */
+
+ IF( EQ_32( piPredEnable[iFBOffset], 1 ) )
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ iQuantValue1 *= iHuffMod;
+ iQuantValue1 = L_add( iQuantValue1, iQuantValue2 );
+ iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] );
+ }
+ ELSE
+ {
+ iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] );
+ iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue2][0] );
+ }
+ }
+ ELSE
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ iQuantValue1 *= iHuffMod;
+ iQuantValue1 = L_add( iQuantValue1, iQuantValue2 );
+ iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] );
+ }
+ ELSE
+ {
+ iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] );
+ iBits = L_add( iBits, pauiHuffmanTable[iQuantValue2][0] );
+ }
+ }
+
+ iFBOffset++;
+ }
+ }
+ ELSE
+ {
+ iFBOffset = L_add( iFBOffset, piBandwidths[b] );
+ }
+ }
+
+ iBlockOffest++;
+ }
+ }
+
+ return iBits;
+}
+
+
+/* Currently only the number of bands in frame */
+static Word32 WriteHeaderInformation(
+ const Word32 iNumBands,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsWritten;
+
+ iBitsWritten = 0;
+ move32();
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 );
+ iBitsWritten = L_add( iBitsWritten, 5 );
+
+ return iBitsWritten;
+}
+
+
+static Word32 WriteMSInformation(
+ const Word32 iNumBands,
+ const Word32 iMSMode,
+ const Word32 *piMSFlags,
+ const Word32 *piLRPhaseDiff,
+ const Word32 *piMSPredCoef,
+ Word32 iNumMSPredBands,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsWritten;
+ Word32 iMSPredAll = (Word32) EQ_32( iNumMSPredBands, iNumBands );
+ move32();
+#ifdef DEBUG_WRITE_MS_PRED
+ Word32 iBitsWrittenTmp = 0;
+ move32();
+#endif
+ iBitsWritten = 0;
+ move32();
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 );
+ iBitsWritten = L_add( iBitsWritten, 2 );
+
+ IF( EQ_32( iMSMode, 3 ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+
+ test();
+ test();
+ IF( EQ_32( iMSMode, 2 ) || ( EQ_32( iMSMode, 3 ) && !iMSPredAll ) )
+ {
+ Word32 n;
+ FOR( n = 0; n < iNumBands; n++ )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ }
+
+#ifdef DEBUG_WRITE_MS_PRED
+ iBitsWrittenTmp = iBitsWritten;
+#endif
+ IF( EQ_32( iMSMode, 3 ) )
+ {
+ Word32 b;
+ Word32 anyNonZero;
+ anyNonZero = 0;
+ move32();
+ FOR( b = 0; b < iNumMSPredBands; b++ )
+ {
+ IF( NE_32( piLRPhaseDiff[b], 0 ) )
+ {
+ anyNonZero = 1;
+ move32();
+ BREAK;
+ }
+ }
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
+ iBitsWritten++;
+
+ IF( anyNonZero )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piLRPhaseDiff[0], PHASE_MIN_VAL ), PHASE_BAND0_BITS );
+ iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS );
+ FOR( b = 1; b < iNumMSPredBands; b++ )
+ {
+ Word32 tabIdx = L_sub( piLRPhaseDiff[b], ENV_DELTA_MIN );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ }
+ }
+
+ anyNonZero = 0;
+ move32();
+ FOR( b = 0; b < iNumMSPredBands; b++ )
+ {
+ IF( NE_32( piMSPredCoef[b], 0 ) )
+ {
+ anyNonZero = 1;
+ move32();
+ BREAK;
+ }
+ }
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 );
+ iBitsWritten++;
+
+ IF( anyNonZero )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piMSPredCoef[0], PRED_MIN_VAL ), PRED_BAND0_BITS );
+ iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS );
+ FOR( b = 1; b < iNumMSPredBands; b++ )
+ {
+ Word32 tabIdx = L_sub( piMSPredCoef[b], ENV_DELTA_MIN );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] );
+ }
+ }
+ }
+#ifdef DEBUG_WRITE_MS_PRED
+ {
+ static FILE *fid = 0;
+ IF( !fid )
+ {
+ fid = fopen( "ms_pred_bitrate.txt", "wt" );
+ }
+ fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/
+ }
+#endif
+
+ return iBitsWritten;
+}
+
+
+static Word32 WriteGroupInformation(
+ const Word32 iChannels,
+ const Word32 iCommonGrouping,
+ const Word32 *piNumGroups,
+ Word32 **ppiGroupLengths,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 c, k, n, iBitsWritten;
+
+ iBitsWritten = 0;
+ move32();
+ test();
+ IF( EQ_32( iChannels, 2 ) && EQ_32( iCommonGrouping, 1 ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+
+ FOR( n = 0; n < piNumGroups[0]; n++ )
+ {
+ FOR( k = 1; k < ppiGroupLengths[0][n]; k++ )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ IF( LT_32( n, L_sub( piNumGroups[0], 1 ) ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ }
+ }
+ ELSE IF( EQ_32( iChannels, 2 ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+
+ FOR( c = 0; c < iChannels; c++ )
+ {
+ FOR( n = 0; n < piNumGroups[c]; n++ )
+ {
+ FOR( k = 1; k < ppiGroupLengths[c][n]; k++ )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( c = 0; c < iChannels; c++ )
+ {
+ FOR( n = 0; n < piNumGroups[c]; n++ )
+ {
+ FOR( k = 1; k < ppiGroupLengths[c][n]; k++ )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+
+ IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ }
+ }
+ }
+
+ return iBitsWritten;
+}
+
+
+static Word32 WriteRMSEnvelope(
+ const Word32 iChannels,
+ const Word32 *piNumGroups,
+ const Word32 iNumBands,
+ Word32 ***pppiRMSEnvelope,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 k, n;
+ Word32 iBitsWritten;
+
+ iBitsWritten = 0;
+ move32();
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ FOR( k = 0; k < piNumGroups[n]; k++ )
+ {
+ Word32 b;
+ Word32 iLastRMSVal;
+
+ iLastRMSVal = pppiRMSEnvelope[n][k][0];
+ move32();
+ iLastRMSVal = GT_32( iLastRMSVal, ENV_MIN ) ? iLastRMSVal : ENV_MIN;
+ move32();
+ iLastRMSVal = LT_32( iLastRMSVal, ENV_MAX ) ? iLastRMSVal : ENV_MAX;
+ move32();
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iLastRMSVal, ENV_MIN ), ENV0_BITS );
+ iBitsWritten = L_add( iBitsWritten, ENV0_BITS );
+
+ FOR( b = 1; b < iNumBands; b++ )
+ {
+ Word32 iDelta;
+
+ iDelta = L_sub( pppiRMSEnvelope[n][k][b], iLastRMSVal );
+ iDelta = GT_32( iDelta, ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN;
+ move32();
+ iDelta = LT_32( iDelta, ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX;
+ move32();
+ iDelta = L_sub( iDelta, ENV_DELTA_MIN );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] );
+ iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[iDelta][0] );
+
+ iLastRMSVal = pppiRMSEnvelope[n][k][b];
+ move32();
+ }
+ }
+ }
+
+ return iBitsWritten;
+}
+
+
+static Word32 WriteAllocInformation(
+ const Word32 iAllocOffset,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsWritten;
+
+ iBitsWritten = 0;
+ move32();
+
+ IF( LT_32( iAllocOffset, MIN_ALLOC_OFFSET ) || GT_32( iAllocOffset, MAX_ALLOC_OFFSET ) )
+ {
+ printf( "Serious error\n" );
+ }
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iAllocOffset, MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS );
+ iBitsWritten = L_add( iBitsWritten, ALLOC_OFFSET_BITS );
+
+ return iBitsWritten;
+}
+
+
+static Word32 WriteLCLDData(
+ const Word32 *piNumGroups,
+ Word32 **ppiGroupLengths,
+ const Word32 iNumBands,
+ const Word32 iNumChannels,
+ Word32 **ppiPredEnable,
+ const Word32 iNumSubSets,
+ const Word32 iSubSetId,
+ Word32 ***pppiAlloc,
+ Word32 ***pppiSignReal,
+ Word32 ***pppiSignImag,
+ Word32 ***pppiQReal,
+ Word32 ***pppiQImag,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word32 iBitsWritten;
+ Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1];
+ Word32 s;
+ Word32 iSet = iSubSetId;
+
+ iBitsWritten = 0;
+ move32();
+ FOR( s = 0; s < iNumSubSets; ( s++, iSet-- ) )
+ {
+ Word32 ch;
+ IF( LT_32( iSet, 0 ) )
+ {
+ iSet = L_sub( iNumSubSets, 1 );
+ }
+
+ FOR( ch = 0; ch < iNumChannels; ch++ )
+ {
+ Word32 iBlockOffest = 0;
+ move32();
+ Word32 n;
+ FOR( n = 0; n < piNumGroups[ch]; n++ )
+ {
+ Word32 k;
+ FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ )
+ {
+ Word32 iFBOffset;
+ FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets )
+ {
+ Word32 b;
+ Word32 iAlloc;
+ Word32 iHuffDim;
+ Word32 iHuffMod;
+
+ b = c_aiBandIdPerLcldBand[iFBOffset];
+ move32();
+
+ iAlloc = pppiAlloc[ch][n][b];
+ move32();
+
+ iHuffDim = c_aiHuffmanDim[iAlloc];
+ move32();
+ iHuffMod = c_aiHuffmanMod[iAlloc];
+ move32();
+
+ IF( GT_32( iAlloc, 0 ) )
+ {
+ const UWord16( *pauiHuffmanTable )[2] = NULL;
+ const UWord16( *pauiHuffmanTableDPCM )[2] = NULL;
+ Word32 iQuantValue1;
+ Word32 iQuantValue2;
+ pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc];
+ pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc];
+
+ iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset];
+ move32();
+ iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset];
+ move32();
+#ifdef LCLD_HANDLE_PRED_START_SAMPLE
+ IF( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) )
+#else
+ IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) )
+#endif
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ Word32 iSymbol;
+ iSymbol = iQuantValue1;
+ move32();
+ iSymbol *= iHuffMod;
+ iSymbol = L_add( iSymbol, iQuantValue2 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iSymbol][0] );
+ }
+ ELSE
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue1][0] );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue2][0] );
+ }
+ }
+ ELSE
+ {
+ IF( EQ_32( iHuffDim, 2 ) )
+ {
+ Word32 iSymbol;
+ iSymbol = iQuantValue1;
+ move32();
+ iSymbol *= iHuffMod;
+ iSymbol = L_add( iSymbol, iQuantValue2 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iSymbol][0] );
+ }
+ ELSE
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue1][0] );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] );
+ iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue2][0] );
+ }
+ }
+
+ IF( GT_32( iQuantValue1, 0 ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ IF( GT_32( iQuantValue2, 0 ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 );
+ iBitsWritten = L_add( iBitsWritten, 1 );
+ }
+ }
+ }
+ iBlockOffest++;
+ }
+ }
+ }
+ }
+
+ return iBitsWritten;
+}
+static Word32 ComputeAllocation(
+ const Word32 iChannels,
+ const Word32 *piNumGroups,
+ Word32 **ppiGroupLengths,
+ const Word32 iNumBands,
+ const Word32 *piBandwidths,
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx,
+ Word16 q_final,
+ Word32 ***pppiSMR,
+ const Word32 iAvailableBits,
+ Word32 *piAllocOffset,
+ Word32 ***pppiAlloc,
+ Word32 ***pppiQReal,
+ Word32 ***pppiQImag,
+ Word32 ***pppiSignReal,
+ Word32 ***pppiSignImag,
+ PredictionEncoder *psPredictionEncoder )
+{
+ Word32 iBitsUsed, iDone, iDelta;
+ Word32 b, k, n;
+ Word32 iLimitAllocOffset;
+
+ iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */
+ move32();
+ iDone = 0;
+ move32();
+ iDelta = -MIN_ALLOC_OFFSET;
+ move32();
+ *piAllocOffset = 0;
+ move32();
+ WHILE( EQ_32( iDone, 0 ) )
+ {
+ iBitsUsed = ALLOC_OFFSET_BITS;
+ move32();
+ iLimitAllocOffset = *piAllocOffset;
+ move32();
+ iLimitAllocOffset = GT_32( iLimitAllocOffset, MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET;
+ iLimitAllocOffset = LT_32( iLimitAllocOffset, MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET;
+
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ FOR( k = 0; k < piNumGroups[n]; k++ )
+ {
+ FOR( b = 0; b < iNumBands; b++ )
+ {
+ Word32 iAlloc;
+ iAlloc = ( L_shr( L_add( pppiSMR[n][k][b], L_mult0( extract_l( iLimitAllocOffset ), ALLOC_OFFSET_SCALE ) ), 5 ) );
+ iAlloc = GT_32( iAlloc, MIN_ALLOC ) ? iAlloc : MIN_ALLOC;
+ iAlloc = LT_32( iAlloc, MAX_ALLOC ) ? iAlloc : MAX_ALLOC;
+ pppiAlloc[n][k][b] = iAlloc;
+ move32();
+ }
+ }
+ IF( psPredictionEncoder->iNumSubSets > 1 )
+ {
+ mvl2l( psPredictionEncoder->ppfPredStateReal_fx[n], psPredictionEncoder->ppfPredStateRealTmp_fx[n], LCLD_BANDS );
+ mvl2l( psPredictionEncoder->ppfPredStateImag_fx[n], psPredictionEncoder->ppfPredStateImagTmp_fx[n], LCLD_BANDS );
+ }
+
+ QuantizeSpectrumDPCM_Opt( piNumGroups[n],
+ (const Word32 *) ppiGroupLengths[n],
+ iNumBands,
+ piBandwidths,
+ pppiAlloc[n],
+ pppfReal_fx[n],
+ pppfImag_fx[n],
+ q_final,
+ pppiQReal[n],
+ pppiQImag[n],
+ pppiSignReal[n],
+ pppiSignImag[n],
+ psPredictionEncoder->iNumSubSets,
+ psPredictionEncoder->iSubSetId,
+ psPredictionEncoder->ppiPredBandEnable[n],
+ psPredictionEncoder->ppfA1Real_fx[n],
+ psPredictionEncoder->ppfA1Imag_fx[n],
+ psPredictionEncoder->ppfPredStateRealTmp_fx[n],
+ psPredictionEncoder->ppfPredStateImagTmp_fx[n] );
+ iBitsUsed = L_add( iBitsUsed, CountLCLDBits( piNumGroups[n],
+ (const Word32 *) ppiGroupLengths[n],
+ iNumBands,
+ piBandwidths,
+ (const Word32 *) psPredictionEncoder->ppiPredBandEnable[n],
+ pppiAlloc[n],
+ pppiQReal[n],
+ pppiQImag[n] ) );
+ }
+
+ IF( LE_32( *piAllocOffset, MIN_ALLOC_OFFSET ) && GT_32( iBitsUsed, iAvailableBits ) )
+ {
+#ifdef DEBUG_VERBOSE
+ printf( "Frame can not be coded with the number of bits available\n" );
+#endif
+ // iLastError = ENC_ERROR_STREAM_FAILURE;
+ return -1;
+ }
+ ELSE IF( GE_32( *piAllocOffset, MAX_ALLOC_OFFSET ) && LT_32( iBitsUsed, iAvailableBits ) )
+ {
+ *piAllocOffset = MAX_ALLOC_OFFSET;
+ iDone++;
+ }
+ ELSE
+ {
+ IF( EQ_32( iDelta, 0 ) && GT_32( iBitsUsed, iAvailableBits ) )
+ {
+ iDelta = 1;
+ }
+ ELSE IF( EQ_32( iDelta, 0 ) && LT_32( iBitsUsed, iAvailableBits ) )
+ {
+ iDone++;
+ }
+ ELSE IF( EQ_32( iBitsUsed, iAvailableBits ) )
+ {
+ iDone++;
+ }
+
+ IF( GT_32( iBitsUsed, iAvailableBits ) )
+ {
+ *piAllocOffset -= iDelta;
+ iDelta = L_shr( iDelta, 1 );
+ }
+ ELSE IF( LT_32( iBitsUsed, iAvailableBits ) )
+ {
+ *piAllocOffset += iDelta;
+ iDelta = L_shr( iDelta, 1 );
+ }
+ }
+ }
+ IF( GT_32( psPredictionEncoder->iNumSubSets, 1 ) )
+ {
+ FOR( n = 0; n < iChannels; n++ )
+ {
+ mvl2l( psPredictionEncoder->ppfPredStateRealTmp_fx[n], psPredictionEncoder->ppfPredStateReal_fx[n], LCLD_BANDS );
+ mvl2l( psPredictionEncoder->ppfPredStateImagTmp_fx[n], psPredictionEncoder->ppfPredStateImag_fx[n], LCLD_BANDS );
+ }
+ }
+ return iBitsUsed;
+}
+#endif
diff --git a/lib_isar/isar_lcld_prot.h b/lib_isar/isar_lcld_prot.h
new file mode 100644
index 0000000000000000000000000000000000000000..a37134857efdb4f4aabf98a94fd864becd32be60
--- /dev/null
+++ b/lib_isar/isar_lcld_prot.h
@@ -0,0 +1,457 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_LCLD_PROT_H
+#define ISAR_LCLD_PROT_H
+
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "typedef.h"
+#include "common_api_types.h"
+#include "isar_lcld_rom_tables.h"
+// #include "prot.h"
+/* clang-format off */
+
+typedef struct LCLD_ENCODER LCLDEncoder;
+
+ivas_error CreateLCLDEncoder(
+ LCLDEncoder **psLCLDEncoder_out,
+ const Word32 iSampleRate,
+ const Word32 iChannels,
+ const Word32 iTargetBitRate,
+ const Word32 iAllowSidePred,
+ const Word16 iNumBlocks,
+ const Word16 iNumSubSets,
+ const Word32 iRealOnlyOut);
+void DeleteLCLDEncoder(
+ LCLDEncoder *psLCLDEncoder
+);
+
+Word32 EncodeLCLDFrame(
+ LCLDEncoder *psLCLDEncoder,
+ Word32 ***pppfLCLDReal_fx,
+ Word32 ***pppfLCLDImag_fx,
+ Word32 *piNumiBites,
+ const Word32 available_bits,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word16 *q_final);
+
+Word32 GetNumGroups(
+ LCLDEncoder *psLCLDEncoder
+);
+
+
+typedef struct LCLD_DECODER LCLDDecoder;
+
+ivas_error CreateLCLDDecoder(
+ LCLDDecoder **psLCLDDecoder_out,
+ const Word32 iSampleRate,
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ const Word32 iRealOnlyOut);
+
+
+void DeleteLCLDDecoder(
+ LCLDDecoder *psLCLDDecoder
+);
+
+Word32 DecodeLCLDFrame(
+ LCLDDecoder *psLCLDDecoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 ***pppfLCLDReal_fx,
+ Word32 ***pppfLCLDImag_fx,
+ Word16 Q_in,
+ Word16 *Q_out
+);
+
+/*----------------------------------------------------------------------------------*
+ * MSPred prototypes
+ *----------------------------------------------------------------------------------*/
+Word32 quantPhase_fx(
+ Word32 phase,
+ Word16 exp);
+
+int32_t quantPhase(
+ float phase
+);
+
+void cplxmult(
+ float *pr1,
+ float *pi1,
+ float r2,
+ float i2
+);
+void cplxmult_fx(
+ Word32 *pr1,
+ Word32 *pi1,
+ Word32 r2,
+ Word32 i2
+);
+
+Word32 requantPhase(
+ Word32 phaseQ
+);
+
+Word32 quantPred_fx(
+ const Word32 pred,
+ Word16 exp);
+int32_t quantPred(
+ const float pred
+);
+
+float dequantPhase(
+ const int32_t phaseQ
+);
+
+float dequantPred(
+ int32_t predQ
+);
+Word32 dequantPred_fx(
+ Word32 predQ
+);
+Word32 PrepEncode(
+ Word32 *piQuant,
+ const Word32 *piMSFlags,
+ const Word32 numBands
+);
+
+void EncodePhase(
+ Word32 *phaseQuant,
+ const Word32 numMSBands,
+ const Word32 diffDim
+);
+
+void DecodePhase(
+ Word32 *phaseQuant,
+ const Word32 numMSBands,
+ const Word32 diffDim
+);
+
+Word32 EncodePredCoef(
+ Word32 *predQuant,
+ const Word32 numMSBands
+);
+
+void DecodePredCoef(
+ Word32 *phaseQuant,
+ const Word32 numMSBands
+);
+
+void writeMSPred(
+ int32_t *phaseQuant,
+ int32_t *predQuant,
+ const int32_t MSMode,
+ const int32_t numMSBands,
+ int32_t numBands,
+ void *fid,
+ int32_t *piMsFlags
+);
+
+Word32 CountMSBits(
+ Word32 iNumBands,
+ const Word32 iMSMode,
+ const Word32 *piMSFlags,
+ const Word32 *piLRPhaseDiff,
+ const Word32 *piMSPredCoef
+);
+
+
+/*----------------------------------------------------------------------------------*
+ * NoiseGen prototypes
+ *----------------------------------------------------------------------------------*/
+
+typedef struct NOISE_GEN
+{
+ int32_t iNoiseBufferLength;
+ int32_t iNoiseBufferMask;
+ int32_t iNoiseBufferIndex;
+ float *pfNoiseBuffer;
+} NoiseGen;
+
+void DeleteNoiseGen(
+ NoiseGen *psNoiseGen
+);
+
+inline float GetNoise( NoiseGen *psNoiseGen )
+{
+ float fNoiseSample;
+
+ fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex];
+ psNoiseGen->iNoiseBufferIndex++;
+ psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask;
+
+ return fNoiseSample;
+}
+inline Word32 GetNoise_fx( NoiseGen *psNoiseGen )
+{
+ Word32 fNoiseSample;
+
+ fNoiseSample = (Word32) (psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]* (1<<14));
+ psNoiseGen->iNoiseBufferIndex++;
+ psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask;
+
+ return fNoiseSample;
+}
+
+/*----------------------------------------------------------------------------------*
+ * PereptualModel prototypes
+ *----------------------------------------------------------------------------------*/
+
+extern void PerceptualModel(
+ const int32_t iMaxQuantBands,
+ const int32_t *piRMSEnvelope,
+ int32_t *piExcitation,
+ int32_t *piSMR
+);
+extern void PerceptualModel_fx(
+ const Word32 iMaxQuantBands,
+ const Word32 *piRMSEnvelope,
+ Word32 *piExcitation,
+ Word32 *piSMR
+);
+
+extern void PerceptualModelStereo_fx(
+ const Word32 iMaxQuantBands,
+ const Word32 *piMSFlags,
+ const Word32 *piRMSEnvelope0,
+ const Word32 *piRMSEnvelope1,
+ Word32 *piExcitation0,
+ Word32 *piExcitation1,
+ Word32 *piSMR0,
+ Word32 *piSMR1
+);
+extern void PerceptualModelStereo(
+ const int32_t iMaxQuantBands,
+ const int32_t *piMSFlags,
+ const int32_t *piRMSEnvelope0,
+ const int32_t *piRMSEnvelope1,
+ int32_t *piExcitation0,
+ int32_t *piExcitation1,
+ int32_t *piSMR0,
+ int32_t *piSMR1
+);
+
+
+/*----------------------------------------------------------------------------------*
+ * PredEncoder/PredDecoder prototypes
+ *----------------------------------------------------------------------------------*/
+
+typedef struct PREDICTION_ENCODER
+{
+ int32_t iChannels;
+ int32_t iNumBlocks;
+
+ int32_t iSubSetId;
+ int32_t iNumSubSets;
+ int32_t iMaxNumPredBands;
+ Word32 ***pppfInpBufReal_fx; /* channels, LCLD_PRED_WIN_LEN, bands */
+ Word32 ***pppfInpBufImag_fx;
+ Word32 **ppfPredStateReal_fx; /* channels, bands */
+ Word32 **ppfPredStateImag_fx;
+ Word32 **ppfPredStateRealTmp_fx;
+ Word32 **ppfPredStateImagTmp_fx;
+ Word32 **ppfInpPrevReal_fx; /* channels, bands */
+ Word32 **ppfInpPrevImag_fx;
+ float ***pppfInpBufReal; /* channels, LCLD_PRED_WIN_LEN, bands */
+ float ***pppfInpBufImag;
+ float **ppfPredStateReal; /* channels, bands */
+ float **ppfPredStateImag;
+ float **ppfPredStateRealTmp;
+ float **ppfPredStateImagTmp;
+ float **ppfInpPrevReal; /* channels, bands */
+ float **ppfInpPrevImag;
+ Word32 pfRxxReal_fx[2];
+ Word32 pfRxxImag_fx[2];
+ float pfRxxReal[2];
+ float pfRxxImag[2];
+
+ int32_t *piPredChanEnable;
+ int32_t *piNumPredBands;
+ int32_t **ppiPredBandEnable;
+
+ Word32 **ppfA1Real_fx;
+ Word32 **ppfA1Imag_fx;
+ float **ppfA1Real;
+ float **ppfA1Imag;
+
+ int32_t **ppiA1Mag;
+ int32_t **ppiA1Phase;
+} PredictionEncoder;
+
+ivas_error CreatePredictionEncoder_fx(
+ PredictionEncoder **psPredictionEncoder_out,
+ const Word32 iChannels,
+ const Word32 iNumBlocks,
+ const Word32 iNumSubSets,
+ const Word32 iMaxNumPredBands );
+
+void DeletePredictionEncoder_fx(
+ PredictionEncoder *psPredictionEncoder );
+ivas_error CreatePredictionEncoder(
+ PredictionEncoder **psPredictionEncoder_out,
+ const int32_t iChannels,
+ const int32_t iNumBlocks,
+ const int32_t iNumSubSets,
+ const int32_t iMaxNumPredBands
+);
+
+void DeletePredictionEncoder(
+ PredictionEncoder *psPredictionEncoder
+);
+
+void ComputePredictors(
+ PredictionEncoder *psPredictionEncoder,
+ float ***pppfReal,
+ float ***pppfImag
+);
+void ComputePredictors_fx(
+ PredictionEncoder *psPredictionEncoder,
+ Word32 ***pppfReal_fx, //Q12?
+ Word32 ***pppfImag_fx); //Q12?
+
+
+Word32 WritePredictors(
+ PredictionEncoder *psPredictionEncoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits );
+
+typedef struct PREDICTION_DECODER
+{
+ int32_t iChannels;
+ int32_t iNumBlocks;
+ int32_t iSubSetId;
+ int32_t iNumSubSets;
+ Word32 **ppfPredStateReal_fx;
+ Word32 **ppfPredStateImag_fx;
+
+ int32_t *piPredChanEnable;
+ int32_t **ppiPredBandEnable;
+ /* PLC_IMPROVEMENT */
+ int32_t **ppiDecodingUnresolved;
+ int32_t **ppiDecodingFailed;
+ int32_t **ppiDecodingFailedPrev;
+ Word32 **ppfA1Real_fx; /* Q31 */
+ Word32 **ppfA1Imag_fx; /* Q31 */
+
+ int32_t **ppiA1Mag;
+ int32_t **ppiA1Phase;
+
+ Word32 pfMagLUT_fx[1 << PRED_QUNAT_FILTER_MAG_BITS]; /* Q31 */
+ Word32 pfP2RRealLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */
+ Word32 pfP2RImagLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */
+
+} PredictionDecoder;
+
+
+ivas_error CreatePredictionDecoder_fx(
+ PredictionDecoder **psPredictionDecoder_out,
+ const Word32 iChannels,
+ const Word32 iNumBlocks );
+
+void DeletePredictionDecoder_fx(
+ PredictionDecoder *psPredictionDecoder );
+
+Word32 ReadPredictors_fx(
+ PredictionDecoder *psPredictionDecoder,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits
+);
+
+/* PLC_IMPROVEMENT */
+void UpdatePredictionSubSetId(
+ PredictionEncoder *psPredictionEncoder);
+
+void SetDecodingUnresolved(
+ LCLDDecoder *psLCLDDecoder);
+
+int32_t AnyDecodingFailedPrev(
+ LCLDDecoder *psLCLDDecoder);
+
+int32_t AnyDecodingFailed(
+ LCLDDecoder *psLCLDDecoder);
+
+int32_t **GetDecodingFailedStatus(
+ LCLDDecoder *psLCLDDecoder);
+
+int16_t GetNumSubSets(
+ LCLDDecoder *psLCLDDecoder);
+
+int32_t **GetDecodingFailedPrevStatus(
+ LCLDDecoder *psLCLDDecoder);
+
+void SetDecodingPassed(
+ PredictionDecoder *psPredictionDecoder);
+
+void UpdateDecodingUnresolved(
+ PredictionDecoder *psPredictionDecoder);
+
+void UpdateDecodingFailedStatus(
+ PredictionDecoder *psPredictionDecoder);
+
+int32_t AnyDecodingUnresolved(
+ PredictionDecoder *psPredictionDecoder);
+
+void ApplyInversePredictors_fx(
+ PredictionDecoder *psPredictionDecoder,
+ Word32 ***pppfReal,
+ Word32 ***pppfImag
+);
+
+
+/*----------------------------------------------------------------------------------*
+ * RMSEnvGrouping prototypes
+ *----------------------------------------------------------------------------------*/
+
+typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping;
+
+RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping(
+ const int32_t iNumBlocks
+);
+
+void DeleteRMSEnvelopeGrouping(
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping
+);
+void ComputeEnvelopeGrouping(
+ RMSEnvelopeGrouping *psRMSEnvelopeGrouping,
+ const int32_t iChannels,
+ const int32_t iNumBands,
+ const int32_t *piBandwidths,
+ Word32 ***pppfReal_fx,
+ Word32 ***pppfImag_fx,
+ int32_t *piNumGroups,
+ int32_t *piGroupLengths,
+ int32_t ***pppiRMSEnvelope ,
+ Word16 q_final
+);
+
+#endif
+/* clang-format on */
+
+#endif /* _LCLD_ENCODER_H_ */
diff --git a/lib_isar/isar_lcld_rom_tables.c b/lib_isar/isar_lcld_rom_tables.c
new file mode 100644
index 0000000000000000000000000000000000000000..d101c0eacfd7947b39e847af3fb12e679b7dfa84
--- /dev/null
+++ b/lib_isar/isar_lcld_rom_tables.c
@@ -0,0 +1,21207 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include "isar_lcld_rom_tables.h"
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "wmc_auto.h"
+#include "prot.h"
+#include "isar_lcld_prot.h"
+#include
+
+/* clang-format off */
+const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60
+};
+
+const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18,
+ 18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22
+};
+/* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */
+const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] =
+{
+ { -1.00000000f, -0.00000000f },
+ { -0.96592583f, -0.25881905f },
+ { -0.86602540f, -0.50000000f },
+ { -0.70710678f, -0.70710678f },
+ { -0.50000000f, -0.86602540f },
+ { -0.25881905f, -0.96592583f },
+ { 0.00000000f, -1.00000000f },
+ { 0.25881905f, -0.96592583f },
+ { 0.50000000f, -0.86602540f },
+ { 0.70710678f, -0.70710678f },
+ { 0.86602540f, -0.50000000f },
+ { 0.96592583f, -0.25881905f },
+ { 1.00000000f, 0.00000000f },
+ { 0.96592583f, 0.25881905f },
+ { 0.86602540f, 0.50000000f },
+ { 0.70710678f, 0.70710678f },
+ { 0.50000000f, 0.86602540f },
+ { 0.25881905f, 0.96592583f },
+ { 0.00000000f, 1.00000000f },
+ { -0.25881905f, 0.96592583f },
+ { -0.50000000f, 0.86602540f },
+ { -0.70710678f, 0.70710678f },
+ { -0.86602540f, 0.50000000f },
+ { -0.96592583f, 0.25881905f },
+ { -1.00000000f, 0.00000000f }
+};
+
+const Word32 c_afRotRealImag_fx[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = /*Q31*/
+{
+ {-2147483647,0,},
+ {-2074309888,-555809664,},
+ {-1859775360,-1073741824,},
+ {-1518500224,-1518500224,},
+ {-1073741824,-1859775360,},
+ {-555809664,-2074309888,},
+ {0,-2147483647,},
+ {555809664,-2074309888,},
+ {1073741824,-1859775360,},
+ {1518500224,-1518500224,},
+ {1859775360,-1073741824,},
+ {2074309888,-555809664,},
+ {2147483647,0,},
+ {2074309888,555809664,},
+ {1859775360,1073741824,},
+ {1518500224,1518500224,},
+ {1073741824,1859775360,},
+ {555809664,2074309888,},
+ {0,2147483647,},
+ {-555809664,2074309888,},
+ {-1073741824,1859775360,},
+ {-1518500224,1518500224,},
+ {-1859775360,1073741824,},
+ {-2074309888,555809664,},
+ {-2147483647,0,},
+
+};
+/* Move this to perceptual model ? */
+const int32_t c_aiBandwidths48[MAX_BANDS_48] =
+{
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 6,
+ 6,
+ 7,
+ 10,
+};
+
+
+const float c_afScaleFactor[ALLOC_TABLE_SIZE] = {
+ 0.0f,
+ 0.353553390593f,
+ 0.420448207627f,
+ 0.500000000000f,
+ 0.594603557501f,
+ 0.707106781187f,
+ 0.840896415254f,
+ 1.000000000000f,
+ 1.189207115003f,
+ 1.414213562373f,
+ 1.681792830507f,
+ 2.000000000000f,
+ 2.378414230005f,
+ 2.828427124746f,
+ 3.363585661015f,
+ 4.0f,
+ 4.756828460011f,
+ 5.656854249492f,
+ 6.727171322030f,
+ 8.0f,
+ 9.513656920022f,
+ 11.31370849898f,
+ 13.45434264406f,
+ 16.00000000000f,
+ 19.02731384004f,
+ 22.62741699797f,
+ 26.90868528812f,
+ 32.000000000000000f,
+ 38.054627680087073f,
+ 45.254833995939038f,
+ 53.817370576237735f,
+ 64.000000000000000f,
+};
+const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE] = {
+ //Q24
+ 0,
+ 5931641,
+ 7053950,
+ 8388608,
+ 9975792,
+ 11863283,
+ 14107901,
+ 16777216,
+ 19951584,
+ 23726566,
+ 28215802,
+ 33554432,
+ 39903168,
+ 47453132,
+ 56431604,
+ 67108864,
+ 79806336,
+ 94906264,
+ 112863208,
+ 134217728,
+ 159612672,
+ 189812528,
+ 225726416,
+ 268435456,
+ 319225344,
+ 379625056,
+ 451452832,
+ 536870912,
+ 638450688,
+ 759250112,
+ 902905664,
+ 1073741824,
+};
+const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = {
+ 0.0f,
+ 2.367513562373095f,
+ 2.046407115002721f,
+ 1.775900000000000f,
+ 1.536446415253715f,
+ 1.323056781186548f,
+ 1.132903557501360f,
+ 0.965800000000000f,
+ 0.821348207626857f,
+ 0.695103390593274f,
+ 0.587801778750680f,
+ 0.495800000000000f,
+ 0.418124103813429f,
+ 0.352176695296637f,
+ 0.296200889375340f,
+ 0.249400000000000f,
+ 0.209812051906714f,
+ 0.176538347648318f,
+ 0.148525444687670f,
+ 0.124900000000000f,
+ 0.105056025953357f,
+ 0.088388347648318f,
+ 0.074325444687670f,
+ 0.062500000000000f,
+ 0.052556025953357f,
+ 0.044194173824159f,
+ 0.037162722343835f,
+ 0.031250000000000f,
+ 0.026278012976679f,
+ 0.022097086912080f,
+ 0.018581361171918f,
+ 0.015625000000000f,
+};
+const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE] = {
+ //Q29
+ 0,
+ 1271049216,
+ 1098656512,
+ 953429056,
+ 824873408,
+ 710310720,
+ 608222976,
+ 518509920,
+ 440957952,
+ 373180800,
+ 315573664,
+ 266180592,
+ 224478672,
+ 189073424,
+ 159021648,
+ 133895608,
+ 112641984,
+ 94778304,
+ 79738992,
+ 67055176,
+ 56401524,
+ 47453132,
+ 39903168,
+ 33554432,
+ 28215802,
+ 23726566,
+ 19951584,
+ 16777216,
+ 14107901,
+ 11863283,
+ 9975792,
+ 8388608,
+};
+const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = {
+ 2.32830644e-10f,
+ 3.29272254e-10f,
+ 4.65661287e-10f,
+ 6.58544508e-10f,
+ 9.31322575e-10f,
+ 1.31708902e-09f,
+ 1.86264515e-09f,
+ 2.63417803e-09f,
+ 3.72529030e-09f,
+ 5.26835606e-09f,
+ 7.45058060e-09f,
+ 1.05367121e-08f,
+ 1.49011612e-08f,
+ 2.10734243e-08f,
+ 2.98023224e-08f,
+ 4.21468485e-08f,
+ 5.96046448e-08f,
+ 8.42936970e-08f,
+ 1.19209290e-07f,
+ 1.68587394e-07f,
+ 2.38418579e-07f,
+ 3.37174788e-07f,
+ 4.76837158e-07f,
+ 6.74349576e-07f,
+ 9.53674316e-07f,
+ 1.34869915e-06f,
+ 1.90734863e-06f,
+ 2.69739830e-06f,
+ 3.81469727e-06f,
+ 5.39479661e-06f,
+ 7.62939453e-06f,
+ 1.07895932e-05f,
+ 1.52587891e-05f,
+ 2.15791864e-05f,
+ 3.05175781e-05f,
+ 4.31583729e-05f,
+ 6.10351562e-05f,
+ 8.63167458e-05f,
+ 1.22070312e-04f,
+ 1.72633492e-04f,
+ 2.44140625e-04f,
+ 3.45266983e-04f,
+ 4.88281250e-04f,
+ 6.90533966e-04f,
+ 9.76562500e-04f,
+ 1.38106793e-03f,
+ 1.95312500e-03f,
+ 2.76213586e-03f,
+ 3.90625000e-03f,
+ 5.52427173e-03f,
+ 7.81250000e-03f,
+ 1.10485435e-02f,
+ 1.56250000e-02f,
+ 2.20970869e-02f,
+ 3.12500000e-02f,
+ 4.41941738e-02f,
+ 6.25000000e-02f,
+ 8.83883476e-02f,
+ 1.25000000e-01f,
+ 1.76776695e-01f,
+ 2.50000000e-01f,
+ 3.53553391e-01f,
+ 5.00000000e-01f,
+ 7.07106781e-01f,
+ 1.00000000e+00f,
+ 1.41421356e+00f,
+ 2.00000000e+00f,
+ 2.82842712e+00f,
+ 4.00000000e+00f,
+ 5.65685425e+00f,
+ 8.00000000e+00f,
+ 1.13137085e+01f,
+ 1.60000000e+01f,
+ 2.26274170e+01f,
+ 3.20000000e+01f,
+ 4.52548340e+01f,
+ 6.40000000e+01f,
+ 9.05096680e+01f,
+ 1.28000000e+02f,
+ 1.81019336e+02f,
+ 2.56000000e+02f,
+ 3.62038672e+02f,
+ 5.12000000e+02f,
+ 7.24077344e+02f,
+ 1.02400000e+03f,
+ 1.44815469e+03f,
+ 2.04800000e+03f,
+ 2.89630938e+03f,
+ 4.09600000e+03f,
+ 5.79261875e+03f,
+ 8.19200000e+03f,
+ 1.15852375e+04f,
+ 1.63840000e+04f,
+ 2.31704750e+04f,
+ 3.27680000e+04f,
+ 4.63409500e+04f,
+ 6.55360000e+04f,
+ 9.26819000e+04f,
+ 1.31072000e+05f,
+ 1.85363800e+05f,
+ 2.62144000e+05f,
+ 3.70727600e+05f,
+ 5.24288000e+05f,
+ 7.41455200e+05f,
+ 1.04857600e+06f,
+ 1.48291040e+06f,
+ 2.09715200e+06f,
+ 2.96582080e+06f,
+ 4.19430400e+06f,
+ 5.93164160e+06f,
+ 8.38860800e+06f,
+ 1.18632832e+07f,
+ 1.67772160e+07f,
+ 2.37265664e+07f,
+ 3.35544320e+07f,
+ 4.74531328e+07f,
+ 6.71088640e+07f,
+ 9.49062656e+07f,
+ 1.34217728e+08f,
+ 1.89812531e+08f,
+ 2.68435456e+08f,
+ 3.79625062e+08f,
+ 5.36870912e+08f,
+ 7.59250125e+08f,
+ 1.07374182e+09f,
+ 1.51850025e+09f,
+ 2.14748365e+09f,
+ 3.03700050e+09f,
+ 4.29496730e+09f,
+};
+
+const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE] =
+{
+ 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, -1, -1, -2
+};
+const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE] = {
+ //Q21
+ 0,
+6291456,
+6291456,
+8388608,
+10485760,
+10485760,
+12582912,
+14680064,
+16777216,
+18874368,
+25165824,
+27262976,
+33554432,
+35651584,
+39845888,
+48234496,
+54525952,
+54525952,
+56623104,
+58720256,
+65011712,
+75497472,
+79691776,
+94371840,
+113246208,
+134217728,
+159383552,
+188743680,
+226492416,
+268435456,
+318767104,
+377487360,
+};
+const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = {
+ 0,
+ 3,
+ 3,
+ 4,
+ 5,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 12,
+ 13,
+ 16,
+ 17,
+ 19,
+ 23,
+ 26,
+ 26,
+ 27,
+ 28,
+ 31,
+ 36,
+ 38,
+ 45,
+ 54,
+ 64,
+ 76,
+ 90,
+ 108,
+ 128,
+ 152,
+ 180,
+};
+const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE] = {
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE] = {
+ 0,
+ 4,
+ 4,
+ 5,
+ 6,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 13,
+ 14,
+ 17,
+ 18,
+ 20,
+ 24,
+ 27,
+ 27,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE] = {
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE] = {
+ 0,
+ 4,
+ 4,
+ 5,
+ 6,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 13,
+ 14,
+ 17,
+ 18,
+ 20,
+ 24,
+ 27,
+ 27,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE] = {
+ 1,
+ 16,
+ 16,
+ 25,
+ 36,
+ 36,
+ 49,
+ 64,
+ 81,
+ 100,
+ 169,
+ 196,
+ 289,
+ 324,
+ 400,
+ 576,
+ 729,
+ 729,
+ 28,
+ 29,
+ 32,
+ 37,
+ 39,
+ 46,
+ 55,
+ 65,
+ 77,
+ 91,
+ 109,
+ 129,
+ 153,
+ 181,
+};
+
+const uint32_t c_aaiRMSEnvHuffEnc[64][2] = {
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0012, 0x000b },
+ { 0x000d, 0x0002 },
+ { 0x000e, 0x0001 },
+ { 0x000e, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000b, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0007, 0x0004 },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0005, 0x0003 },
+ { 0x0004, 0x0002 },
+ { 0x0003, 0x0002 },
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0003 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0007 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x0010, 0x0003 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+};
+
+const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = {
+ {
+ 0x0002ffff,
+ 0x0001ffff,
+ 0x0000001d,
+ 0x00000022,
+ 0x0001001e,
+ 0x0001001e,
+ 0x00010021,
+ 0x00010021,
+ 0x0002001f,
+ 0x0002001f,
+ 0x0002001f,
+ 0x0002001f,
+ 0x00020020,
+ 0x00020020,
+ 0x00020020,
+ 0x00020020,
+ },
+ {
+ 0x0002001b,
+ 0x0002001b,
+ 0x0002001b,
+ 0x0002001b,
+ 0x00020023,
+ 0x00020023,
+ 0x00020023,
+ 0x00020023,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ 0x0003001c,
+ },
+ {
+ 0x0006ffff,
+ 0x0007ffff,
+ 0x0003ffff,
+ 0x0004ffff,
+ 0x0005ffff,
+ 0x00000017,
+ 0x00000018,
+ 0x00000025,
+ 0x00010019,
+ 0x00010019,
+ 0x00010024,
+ 0x00010024,
+ 0x0002001a,
+ 0x0002001a,
+ 0x0002001a,
+ 0x0002001a,
+ },
+ {
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030014,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ 0x00030015,
+ },
+ {
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030016,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ 0x00030026,
+ },
+ {
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030027,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ 0x00030028,
+ },
+ {
+ 0x0009ffff,
+ 0x0008ffff,
+ 0x0000002c,
+ 0x0000002d,
+ 0x00010010,
+ 0x00010010,
+ 0x0001002b,
+ 0x0001002b,
+ 0x0001002e,
+ 0x0001002e,
+ 0x0001002f,
+ 0x0001002f,
+ 0x00020011,
+ 0x00020011,
+ 0x00020011,
+ 0x00020011,
+ },
+ {
+ 0x00020012,
+ 0x00020012,
+ 0x00020012,
+ 0x00020012,
+ 0x00020013,
+ 0x00020013,
+ 0x00020013,
+ 0x00020013,
+ 0x00020029,
+ 0x00020029,
+ 0x00020029,
+ 0x00020029,
+ 0x0002002a,
+ 0x0002002a,
+ 0x0002002a,
+ 0x0002002a,
+ },
+ {
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000c,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ 0x0003000f,
+ },
+ {
+ 0x000bffff,
+ 0x000cffff,
+ 0x000affff,
+ 0x00000031,
+ 0x0002000d,
+ 0x0002000d,
+ 0x0002000d,
+ 0x0002000d,
+ 0x0002000e,
+ 0x0002000e,
+ 0x0002000e,
+ 0x0002000e,
+ 0x00020030,
+ 0x00020030,
+ 0x00020030,
+ 0x00020030,
+ },
+ {
+ 0x0001003a,
+ 0x0001003a,
+ 0x0001003b,
+ 0x0001003b,
+ 0x0001003c,
+ 0x0001003c,
+ 0x0001003d,
+ 0x0001003d,
+ 0x0001003e,
+ 0x0001003e,
+ 0x0001003f,
+ 0x0001003f,
+ 0x0002000b,
+ 0x0002000b,
+ 0x0002000b,
+ 0x0002000b,
+ },
+ {
+ 0x00000000,
+ 0x00000001,
+ 0x00000002,
+ 0x00000003,
+ 0x00000004,
+ 0x00000005,
+ 0x00010006,
+ 0x00010006,
+ 0x00010007,
+ 0x00010007,
+ 0x00010008,
+ 0x00010008,
+ 0x00010009,
+ 0x00010009,
+ 0x0001000a,
+ 0x0001000a,
+ },
+ {
+ 0x00010032,
+ 0x00010032,
+ 0x00010033,
+ 0x00010033,
+ 0x00010034,
+ 0x00010034,
+ 0x00010035,
+ 0x00010035,
+ 0x00010036,
+ 0x00010036,
+ 0x00010037,
+ 0x00010037,
+ 0x00010038,
+ 0x00010038,
+ 0x00010039,
+ 0x00010039,
+ },
+};
+
+const uint16_t c_aauiLCLDHuffEnc1[16][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0005, 0x0001 },
+ { 0x000b, 0x0000 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc2[16][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0005, 0x0001 },
+ { 0x000c, 0x0000 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000b, 0x0003 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc3[25][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000d, 0x0000 },
+ { 0x000d, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x0009, 0x0001 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc4[36][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x0010, 0x0000 },
+ { 0x0010, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000e, 0x0006 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000e, 0x0007 },
+ { 0x0010, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0010, 0x0008 },
+ { 0x0010, 0x0009 },
+ { 0x0010, 0x000a },
+ { 0x0010, 0x000b },
+ { 0x0010, 0x000c },
+ { 0x0010, 0x000d },
+ { 0x0010, 0x000e },
+ { 0x0010, 0x000f },
+ { 0x0010, 0x0010 },
+ { 0x0010, 0x0011 },
+ { 0x000f, 0x0009 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc5[36][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000f, 0x0003 },
+ { 0x0012, 0x0000 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x0011, 0x0008 },
+ { 0x0012, 0x0001 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000d, 0x0001 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0011, 0x0009 },
+ { 0x0011, 0x000a },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+ { 0x0012, 0x000e },
+ { 0x0012, 0x000f },
+ { 0x0011, 0x000b },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc6[49][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x0010, 0x0003 },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0002 },
+ { 0x0010, 0x0004 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x0012, 0x0007 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x0011, 0x0004 },
+ { 0x0014, 0x0006 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0010, 0x0005 },
+ { 0x000f, 0x0003 },
+ { 0x0011, 0x0005 },
+ { 0x0014, 0x0009 },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0013, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc7[64][2] =
+ {
+ { 0x0002, 0x0001 },
+ { 0x0002, 0x0002 },
+ { 0x0005, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000f, 0x0002 },
+ { 0x0015, 0x0000 },
+ { 0x0015, 0x0001 },
+ { 0x0015, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0009, 0x0002 },
+ { 0x000f, 0x0003 },
+ { 0x0014, 0x0011 },
+ { 0x0015, 0x0003 },
+ { 0x0015, 0x0004 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x0010, 0x0002 },
+ { 0x0015, 0x0005 },
+ { 0x0015, 0x0006 },
+ { 0x0015, 0x0007 },
+ { 0x000a, 0x0001 },
+ { 0x0009, 0x0003 },
+ { 0x000c, 0x0001 },
+ { 0x000f, 0x0004 },
+ { 0x0012, 0x0006 },
+ { 0x0015, 0x0008 },
+ { 0x0015, 0x0009 },
+ { 0x0015, 0x000a },
+ { 0x000f, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x0010, 0x0003 },
+ { 0x0012, 0x0007 },
+ { 0x0014, 0x0012 },
+ { 0x0015, 0x000b },
+ { 0x0015, 0x000c },
+ { 0x0015, 0x000d },
+ { 0x0014, 0x0013 },
+ { 0x0014, 0x0014 },
+ { 0x0013, 0x000b },
+ { 0x0014, 0x0015 },
+ { 0x0015, 0x000e },
+ { 0x0015, 0x000f },
+ { 0x0015, 0x0010 },
+ { 0x0015, 0x0011 },
+ { 0x0015, 0x0012 },
+ { 0x0015, 0x0013 },
+ { 0x0015, 0x0014 },
+ { 0x0015, 0x0015 },
+ { 0x0015, 0x0016 },
+ { 0x0015, 0x0017 },
+ { 0x0015, 0x0018 },
+ { 0x0015, 0x0019 },
+ { 0x0015, 0x001a },
+ { 0x0015, 0x001b },
+ { 0x0015, 0x001c },
+ { 0x0015, 0x001d },
+ { 0x0015, 0x001e },
+ { 0x0015, 0x001f },
+ { 0x0015, 0x0020 },
+ { 0x0015, 0x0021 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc8[81][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000f, 0x0002 },
+ { 0x0014, 0x0008 },
+ { 0x0017, 0x0000 },
+ { 0x0017, 0x0001 },
+ { 0x0017, 0x0002 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000f, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0015, 0x000d },
+ { 0x0017, 0x0003 },
+ { 0x0017, 0x0004 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x0010, 0x0002 },
+ { 0x0013, 0x0005 },
+ { 0x0017, 0x0005 },
+ { 0x0017, 0x0006 },
+ { 0x0017, 0x0007 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000b, 0x0001 },
+ { 0x000f, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0016, 0x0015 },
+ { 0x0017, 0x0008 },
+ { 0x0017, 0x0009 },
+ { 0x0017, 0x000a },
+ { 0x000f, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x0010, 0x0003 },
+ { 0x0012, 0x0006 },
+ { 0x0014, 0x0009 },
+ { 0x0017, 0x000b },
+ { 0x0017, 0x000c },
+ { 0x0017, 0x000d },
+ { 0x0017, 0x000e },
+ { 0x0013, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0013, 0x0007 },
+ { 0x0015, 0x000e },
+ { 0x0017, 0x000f },
+ { 0x0017, 0x0010 },
+ { 0x0017, 0x0011 },
+ { 0x0017, 0x0012 },
+ { 0x0017, 0x0013 },
+ { 0x0016, 0x0016 },
+ { 0x0016, 0x0017 },
+ { 0x0015, 0x000f },
+ { 0x0016, 0x0018 },
+ { 0x0017, 0x0014 },
+ { 0x0017, 0x0015 },
+ { 0x0017, 0x0016 },
+ { 0x0017, 0x0017 },
+ { 0x0017, 0x0018 },
+ { 0x0017, 0x0019 },
+ { 0x0017, 0x001a },
+ { 0x0017, 0x001b },
+ { 0x0017, 0x001c },
+ { 0x0017, 0x001d },
+ { 0x0017, 0x001e },
+ { 0x0017, 0x001f },
+ { 0x0017, 0x0020 },
+ { 0x0017, 0x0021 },
+ { 0x0017, 0x0022 },
+ { 0x0017, 0x0023 },
+ { 0x0017, 0x0024 },
+ { 0x0017, 0x0025 },
+ { 0x0017, 0x0026 },
+ { 0x0017, 0x0027 },
+ { 0x0017, 0x0028 },
+ { 0x0017, 0x0029 },
+ { 0x0016, 0x0019 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc9[100][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000d, 0x0002 },
+ { 0x0011, 0x0004 },
+ { 0x0014, 0x000a },
+ { 0x0017, 0x0000 },
+ { 0x0017, 0x0001 },
+ { 0x0017, 0x0002 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0009, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x0010, 0x0004 },
+ { 0x0013, 0x0007 },
+ { 0x0016, 0x0018 },
+ { 0x0017, 0x0003 },
+ { 0x0017, 0x0004 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0008, 0x0002 },
+ { 0x000b, 0x0002 },
+ { 0x000e, 0x0002 },
+ { 0x0011, 0x0005 },
+ { 0x0014, 0x000b },
+ { 0x0016, 0x0019 },
+ { 0x0017, 0x0005 },
+ { 0x0017, 0x0006 },
+ { 0x0009, 0x0003 },
+ { 0x0008, 0x0003 },
+ { 0x000b, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0015, 0x000f },
+ { 0x0017, 0x0007 },
+ { 0x0017, 0x0008 },
+ { 0x0017, 0x0009 },
+ { 0x000d, 0x0005 },
+ { 0x000c, 0x0003 },
+ { 0x000e, 0x0003 },
+ { 0x0010, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0014, 0x000c },
+ { 0x0017, 0x000a },
+ { 0x0016, 0x001a },
+ { 0x0017, 0x000b },
+ { 0x0017, 0x000c },
+ { 0x0011, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0011, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0015, 0x0010 },
+ { 0x0017, 0x000d },
+ { 0x0017, 0x000e },
+ { 0x0017, 0x000f },
+ { 0x0017, 0x0010 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0014, 0x000d },
+ { 0x0015, 0x0011 },
+ { 0x0017, 0x0011 },
+ { 0x0016, 0x001b },
+ { 0x0017, 0x0012 },
+ { 0x0017, 0x0013 },
+ { 0x0017, 0x0014 },
+ { 0x0017, 0x0015 },
+ { 0x0017, 0x0016 },
+ { 0x0015, 0x0012 },
+ { 0x0015, 0x0013 },
+ { 0x0017, 0x0017 },
+ { 0x0016, 0x001c },
+ { 0x0017, 0x0018 },
+ { 0x0017, 0x0019 },
+ { 0x0017, 0x001a },
+ { 0x0017, 0x001b },
+ { 0x0017, 0x001c },
+ { 0x0017, 0x001d },
+ { 0x0017, 0x001e },
+ { 0x0017, 0x001f },
+ { 0x0017, 0x0020 },
+ { 0x0017, 0x0021 },
+ { 0x0017, 0x0022 },
+ { 0x0017, 0x0023 },
+ { 0x0017, 0x0024 },
+ { 0x0017, 0x0025 },
+ { 0x0017, 0x0026 },
+ { 0x0017, 0x0027 },
+ { 0x0017, 0x0028 },
+ { 0x0017, 0x0029 },
+ { 0x0017, 0x002a },
+ { 0x0017, 0x002b },
+ { 0x0017, 0x002c },
+ { 0x0017, 0x002d },
+ { 0x0017, 0x002e },
+ { 0x0017, 0x002f },
+ { 0x0016, 0x001d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc10[169][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0004, 0x0002 },
+ { 0x0005, 0x0002 },
+ { 0x0007, 0x0002 },
+ { 0x000a, 0x0002 },
+ { 0x000e, 0x0004 },
+ { 0x0011, 0x0007 },
+ { 0x0013, 0x0012 },
+ { 0x0016, 0x0000 },
+ { 0x0016, 0x0001 },
+ { 0x0016, 0x0002 },
+ { 0x0016, 0x0003 },
+ { 0x0016, 0x0004 },
+ { 0x0004, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0004 },
+ { 0x0007, 0x0003 },
+ { 0x000a, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x0010, 0x0007 },
+ { 0x0013, 0x0013 },
+ { 0x0015, 0x0035 },
+ { 0x0016, 0x0005 },
+ { 0x0016, 0x0006 },
+ { 0x0016, 0x0007 },
+ { 0x0016, 0x0008 },
+ { 0x0005, 0x0003 },
+ { 0x0004, 0x0005 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0002 },
+ { 0x000b, 0x0002 },
+ { 0x000e, 0x0005 },
+ { 0x0010, 0x0008 },
+ { 0x0013, 0x0014 },
+ { 0x0014, 0x001d },
+ { 0x0016, 0x0009 },
+ { 0x0016, 0x000a },
+ { 0x0016, 0x000b },
+ { 0x0016, 0x000c },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000f, 0x0005 },
+ { 0x0011, 0x0008 },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0016, 0x000d },
+ { 0x0016, 0x000e },
+ { 0x0016, 0x000f },
+ { 0x0016, 0x0010 },
+ { 0x000a, 0x0005 },
+ { 0x0009, 0x0003 },
+ { 0x000b, 0x0003 },
+ { 0x000d, 0x0006 },
+ { 0x000f, 0x0006 },
+ { 0x0011, 0x0009 },
+ { 0x0013, 0x0015 },
+ { 0x0014, 0x0020 },
+ { 0x0016, 0x0011 },
+ { 0x0016, 0x0012 },
+ { 0x0016, 0x0013 },
+ { 0x0016, 0x0014 },
+ { 0x0016, 0x0015 },
+ { 0x000e, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0007 },
+ { 0x000f, 0x0007 },
+ { 0x0011, 0x000a },
+ { 0x0012, 0x000c },
+ { 0x0016, 0x0016 },
+ { 0x0016, 0x0017 },
+ { 0x0016, 0x0018 },
+ { 0x0016, 0x0019 },
+ { 0x0016, 0x001a },
+ { 0x0016, 0x001b },
+ { 0x0016, 0x001c },
+ { 0x0011, 0x000b },
+ { 0x0010, 0x0009 },
+ { 0x0011, 0x000c },
+ { 0x0011, 0x000d },
+ { 0x0013, 0x0016 },
+ { 0x0016, 0x001d },
+ { 0x0016, 0x001e },
+ { 0x0016, 0x001f },
+ { 0x0016, 0x0020 },
+ { 0x0016, 0x0021 },
+ { 0x0016, 0x0022 },
+ { 0x0016, 0x0023 },
+ { 0x0016, 0x0024 },
+ { 0x0014, 0x0021 },
+ { 0x0014, 0x0022 },
+ { 0x0012, 0x000d },
+ { 0x0013, 0x0017 },
+ { 0x0016, 0x0025 },
+ { 0x0016, 0x0026 },
+ { 0x0016, 0x0027 },
+ { 0x0016, 0x0028 },
+ { 0x0016, 0x0029 },
+ { 0x0016, 0x002a },
+ { 0x0016, 0x002b },
+ { 0x0016, 0x002c },
+ { 0x0016, 0x002d },
+ { 0x0015, 0x0036 },
+ { 0x0015, 0x0037 },
+ { 0x0014, 0x0023 },
+ { 0x0015, 0x0038 },
+ { 0x0016, 0x002e },
+ { 0x0016, 0x002f },
+ { 0x0016, 0x0030 },
+ { 0x0016, 0x0031 },
+ { 0x0016, 0x0032 },
+ { 0x0016, 0x0033 },
+ { 0x0016, 0x0034 },
+ { 0x0016, 0x0035 },
+ { 0x0016, 0x0036 },
+ { 0x0016, 0x0037 },
+ { 0x0016, 0x0038 },
+ { 0x0016, 0x0039 },
+ { 0x0016, 0x003a },
+ { 0x0016, 0x003b },
+ { 0x0016, 0x003c },
+ { 0x0016, 0x003d },
+ { 0x0016, 0x003e },
+ { 0x0016, 0x003f },
+ { 0x0016, 0x0040 },
+ { 0x0016, 0x0041 },
+ { 0x0016, 0x0042 },
+ { 0x0016, 0x0043 },
+ { 0x0016, 0x0044 },
+ { 0x0016, 0x0045 },
+ { 0x0016, 0x0046 },
+ { 0x0016, 0x0047 },
+ { 0x0016, 0x0048 },
+ { 0x0016, 0x0049 },
+ { 0x0016, 0x004a },
+ { 0x0016, 0x004b },
+ { 0x0016, 0x004c },
+ { 0x0016, 0x004d },
+ { 0x0016, 0x004e },
+ { 0x0016, 0x004f },
+ { 0x0016, 0x0050 },
+ { 0x0016, 0x0051 },
+ { 0x0016, 0x0052 },
+ { 0x0016, 0x0053 },
+ { 0x0016, 0x0054 },
+ { 0x0016, 0x0055 },
+ { 0x0016, 0x0056 },
+ { 0x0016, 0x0057 },
+ { 0x0016, 0x0058 },
+ { 0x0016, 0x0059 },
+ { 0x0016, 0x005a },
+ { 0x0016, 0x005b },
+ { 0x0016, 0x005c },
+ { 0x0016, 0x005d },
+ { 0x0016, 0x005e },
+ { 0x0016, 0x005f },
+ { 0x0016, 0x0060 },
+ { 0x0016, 0x0061 },
+ { 0x0016, 0x0062 },
+ { 0x0016, 0x0063 },
+ { 0x0016, 0x0064 },
+ { 0x0016, 0x0065 },
+ { 0x0016, 0x0066 },
+ { 0x0016, 0x0067 },
+ { 0x0016, 0x0068 },
+ { 0x0016, 0x0069 },
+ { 0x0015, 0x0039 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc11[196][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x0012, 0x000d },
+ { 0x0014, 0x001f },
+ { 0x0016, 0x0000 },
+ { 0x0016, 0x0001 },
+ { 0x0016, 0x0002 },
+ { 0x0016, 0x0003 },
+ { 0x0016, 0x0004 },
+ { 0x0004, 0x0004 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0006, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x000b, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x0010, 0x0007 },
+ { 0x0012, 0x000e },
+ { 0x0014, 0x0020 },
+ { 0x0016, 0x0005 },
+ { 0x0016, 0x0006 },
+ { 0x0016, 0x0007 },
+ { 0x0016, 0x0008 },
+ { 0x0005, 0x0005 },
+ { 0x0004, 0x0005 },
+ { 0x0006, 0x0004 },
+ { 0x0007, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000e, 0x0006 },
+ { 0x0011, 0x000a },
+ { 0x0012, 0x000f },
+ { 0x0015, 0x003b },
+ { 0x0016, 0x0009 },
+ { 0x0016, 0x000a },
+ { 0x0016, 0x000b },
+ { 0x0016, 0x000c },
+ { 0x0007, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0005 },
+ { 0x0009, 0x0005 },
+ { 0x000b, 0x0005 },
+ { 0x000d, 0x0005 },
+ { 0x000f, 0x0006 },
+ { 0x0012, 0x0010 },
+ { 0x0014, 0x0021 },
+ { 0x0016, 0x000d },
+ { 0x0016, 0x000e },
+ { 0x0016, 0x000f },
+ { 0x0016, 0x0010 },
+ { 0x0016, 0x0011 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000d, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x0011, 0x000b },
+ { 0x0013, 0x0017 },
+ { 0x0014, 0x0022 },
+ { 0x0016, 0x0012 },
+ { 0x0016, 0x0013 },
+ { 0x0016, 0x0014 },
+ { 0x0016, 0x0015 },
+ { 0x0016, 0x0016 },
+ { 0x000c, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0007 },
+ { 0x0010, 0x0008 },
+ { 0x0012, 0x0011 },
+ { 0x0014, 0x0023 },
+ { 0x0015, 0x003c },
+ { 0x0016, 0x0017 },
+ { 0x0016, 0x0018 },
+ { 0x0016, 0x0019 },
+ { 0x0016, 0x001a },
+ { 0x0016, 0x001b },
+ { 0x000f, 0x0008 },
+ { 0x000e, 0x0008 },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x0009 },
+ { 0x0011, 0x000c },
+ { 0x0013, 0x0018 },
+ { 0x0014, 0x0024 },
+ { 0x0016, 0x001c },
+ { 0x0016, 0x001d },
+ { 0x0016, 0x001e },
+ { 0x0016, 0x001f },
+ { 0x0016, 0x0020 },
+ { 0x0016, 0x0021 },
+ { 0x0016, 0x0022 },
+ { 0x0011, 0x000d },
+ { 0x0010, 0x0009 },
+ { 0x0012, 0x0012 },
+ { 0x0012, 0x0013 },
+ { 0x0014, 0x0025 },
+ { 0x0015, 0x003d },
+ { 0x0014, 0x0026 },
+ { 0x0016, 0x0023 },
+ { 0x0016, 0x0024 },
+ { 0x0016, 0x0025 },
+ { 0x0016, 0x0026 },
+ { 0x0016, 0x0027 },
+ { 0x0016, 0x0028 },
+ { 0x0016, 0x0029 },
+ { 0x0014, 0x0027 },
+ { 0x0013, 0x0019 },
+ { 0x0014, 0x0028 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0016, 0x002a },
+ { 0x0016, 0x002b },
+ { 0x0016, 0x002c },
+ { 0x0016, 0x002d },
+ { 0x0016, 0x002e },
+ { 0x0016, 0x002f },
+ { 0x0016, 0x0030 },
+ { 0x0016, 0x0031 },
+ { 0x0016, 0x0032 },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0014, 0x002d },
+ { 0x0016, 0x0033 },
+ { 0x0016, 0x0034 },
+ { 0x0016, 0x0035 },
+ { 0x0016, 0x0036 },
+ { 0x0016, 0x0037 },
+ { 0x0016, 0x0038 },
+ { 0x0016, 0x0039 },
+ { 0x0016, 0x003a },
+ { 0x0016, 0x003b },
+ { 0x0016, 0x003c },
+ { 0x0016, 0x003d },
+ { 0x0016, 0x003e },
+ { 0x0016, 0x003f },
+ { 0x0016, 0x0040 },
+ { 0x0016, 0x0041 },
+ { 0x0016, 0x0042 },
+ { 0x0016, 0x0043 },
+ { 0x0016, 0x0044 },
+ { 0x0016, 0x0045 },
+ { 0x0016, 0x0046 },
+ { 0x0016, 0x0047 },
+ { 0x0016, 0x0048 },
+ { 0x0016, 0x0049 },
+ { 0x0016, 0x004a },
+ { 0x0016, 0x004b },
+ { 0x0016, 0x004c },
+ { 0x0016, 0x004d },
+ { 0x0016, 0x004e },
+ { 0x0016, 0x004f },
+ { 0x0016, 0x0050 },
+ { 0x0016, 0x0051 },
+ { 0x0016, 0x0052 },
+ { 0x0016, 0x0053 },
+ { 0x0016, 0x0054 },
+ { 0x0016, 0x0055 },
+ { 0x0016, 0x0056 },
+ { 0x0016, 0x0057 },
+ { 0x0016, 0x0058 },
+ { 0x0016, 0x0059 },
+ { 0x0016, 0x005a },
+ { 0x0016, 0x005b },
+ { 0x0016, 0x005c },
+ { 0x0016, 0x005d },
+ { 0x0016, 0x005e },
+ { 0x0016, 0x005f },
+ { 0x0016, 0x0060 },
+ { 0x0016, 0x0061 },
+ { 0x0016, 0x0062 },
+ { 0x0016, 0x0063 },
+ { 0x0016, 0x0064 },
+ { 0x0016, 0x0065 },
+ { 0x0016, 0x0066 },
+ { 0x0016, 0x0067 },
+ { 0x0016, 0x0068 },
+ { 0x0016, 0x0069 },
+ { 0x0016, 0x006a },
+ { 0x0016, 0x006b },
+ { 0x0016, 0x006c },
+ { 0x0016, 0x006d },
+ { 0x0016, 0x006e },
+ { 0x0016, 0x006f },
+ { 0x0016, 0x0070 },
+ { 0x0016, 0x0071 },
+ { 0x0016, 0x0072 },
+ { 0x0016, 0x0073 },
+ { 0x0016, 0x0074 },
+ { 0x0016, 0x0075 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc12[289][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0004, 0x0004 },
+ { 0x0005, 0x0004 },
+ { 0x0007, 0x0004 },
+ { 0x0008, 0x0002 },
+ { 0x000b, 0x0004 },
+ { 0x000e, 0x0006 },
+ { 0x0010, 0x0009 },
+ { 0x0012, 0x0014 },
+ { 0x0013, 0x001f },
+ { 0x0016, 0x0000 },
+ { 0x0016, 0x0001 },
+ { 0x0016, 0x0002 },
+ { 0x0016, 0x0003 },
+ { 0x0016, 0x0004 },
+ { 0x0016, 0x0005 },
+ { 0x0016, 0x0006 },
+ { 0x0004, 0x0005 },
+ { 0x0004, 0x0006 },
+ { 0x0005, 0x0005 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000d, 0x0006 },
+ { 0x000f, 0x0008 },
+ { 0x0011, 0x000c },
+ { 0x0013, 0x0020 },
+ { 0x0016, 0x0007 },
+ { 0x0015, 0x0063 },
+ { 0x0016, 0x0008 },
+ { 0x0016, 0x0009 },
+ { 0x0016, 0x000a },
+ { 0x0016, 0x000b },
+ { 0x0016, 0x000c },
+ { 0x0005, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0004 },
+ { 0x0008, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000d, 0x0007 },
+ { 0x0010, 0x000a },
+ { 0x0012, 0x0015 },
+ { 0x0015, 0x0064 },
+ { 0x0016, 0x000d },
+ { 0x0016, 0x000e },
+ { 0x0016, 0x000f },
+ { 0x0016, 0x0010 },
+ { 0x0016, 0x0011 },
+ { 0x0016, 0x0012 },
+ { 0x0016, 0x0013 },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0008, 0x0005 },
+ { 0x000a, 0x0005 },
+ { 0x000c, 0x0005 },
+ { 0x000e, 0x0007 },
+ { 0x0010, 0x000b },
+ { 0x0012, 0x0016 },
+ { 0x0014, 0x0037 },
+ { 0x0015, 0x0065 },
+ { 0x0016, 0x0014 },
+ { 0x0016, 0x0015 },
+ { 0x0016, 0x0016 },
+ { 0x0016, 0x0017 },
+ { 0x0016, 0x0018 },
+ { 0x0016, 0x0019 },
+ { 0x0008, 0x0006 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0007 },
+ { 0x000a, 0x0006 },
+ { 0x000c, 0x0006 },
+ { 0x000e, 0x0008 },
+ { 0x0010, 0x000c },
+ { 0x0011, 0x000d },
+ { 0x0013, 0x0021 },
+ { 0x0015, 0x0066 },
+ { 0x0016, 0x001a },
+ { 0x0016, 0x001b },
+ { 0x0016, 0x001c },
+ { 0x0016, 0x001d },
+ { 0x0016, 0x001e },
+ { 0x0016, 0x001f },
+ { 0x0016, 0x0020 },
+ { 0x000b, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0007 },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x0009 },
+ { 0x0011, 0x000e },
+ { 0x0013, 0x0022 },
+ { 0x0015, 0x0067 },
+ { 0x0015, 0x0068 },
+ { 0x0016, 0x0021 },
+ { 0x0016, 0x0022 },
+ { 0x0016, 0x0023 },
+ { 0x0016, 0x0024 },
+ { 0x0016, 0x0025 },
+ { 0x0016, 0x0026 },
+ { 0x0016, 0x0027 },
+ { 0x000e, 0x000a },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000e, 0x000b },
+ { 0x000f, 0x000a },
+ { 0x0011, 0x000f },
+ { 0x0013, 0x0023 },
+ { 0x0014, 0x0038 },
+ { 0x0016, 0x0028 },
+ { 0x0016, 0x0029 },
+ { 0x0016, 0x002a },
+ { 0x0016, 0x002b },
+ { 0x0016, 0x002c },
+ { 0x0016, 0x002d },
+ { 0x0016, 0x002e },
+ { 0x0016, 0x002f },
+ { 0x0016, 0x0030 },
+ { 0x0010, 0x000d },
+ { 0x000f, 0x000b },
+ { 0x0010, 0x000e },
+ { 0x0010, 0x000f },
+ { 0x0012, 0x0017 },
+ { 0x0013, 0x0024 },
+ { 0x0014, 0x0039 },
+ { 0x0016, 0x0031 },
+ { 0x0016, 0x0032 },
+ { 0x0016, 0x0033 },
+ { 0x0016, 0x0034 },
+ { 0x0016, 0x0035 },
+ { 0x0016, 0x0036 },
+ { 0x0016, 0x0037 },
+ { 0x0016, 0x0038 },
+ { 0x0016, 0x0039 },
+ { 0x0016, 0x003a },
+ { 0x0013, 0x0025 },
+ { 0x0011, 0x0010 },
+ { 0x0011, 0x0011 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0016, 0x003b },
+ { 0x0016, 0x003c },
+ { 0x0016, 0x003d },
+ { 0x0016, 0x003e },
+ { 0x0016, 0x003f },
+ { 0x0016, 0x0040 },
+ { 0x0016, 0x0041 },
+ { 0x0016, 0x0042 },
+ { 0x0016, 0x0043 },
+ { 0x0016, 0x0044 },
+ { 0x0015, 0x0069 },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x0015, 0x006a },
+ { 0x0015, 0x006b },
+ { 0x0015, 0x006c },
+ { 0x0016, 0x0045 },
+ { 0x0016, 0x0046 },
+ { 0x0016, 0x0047 },
+ { 0x0016, 0x0048 },
+ { 0x0016, 0x0049 },
+ { 0x0016, 0x004a },
+ { 0x0016, 0x004b },
+ { 0x0016, 0x004c },
+ { 0x0016, 0x004d },
+ { 0x0016, 0x004e },
+ { 0x0016, 0x004f },
+ { 0x0016, 0x0050 },
+ { 0x0016, 0x0051 },
+ { 0x0015, 0x006d },
+ { 0x0016, 0x0052 },
+ { 0x0016, 0x0053 },
+ { 0x0016, 0x0054 },
+ { 0x0016, 0x0055 },
+ { 0x0016, 0x0056 },
+ { 0x0016, 0x0057 },
+ { 0x0016, 0x0058 },
+ { 0x0016, 0x0059 },
+ { 0x0016, 0x005a },
+ { 0x0016, 0x005b },
+ { 0x0016, 0x005c },
+ { 0x0016, 0x005d },
+ { 0x0016, 0x005e },
+ { 0x0016, 0x005f },
+ { 0x0016, 0x0060 },
+ { 0x0016, 0x0061 },
+ { 0x0016, 0x0062 },
+ { 0x0016, 0x0063 },
+ { 0x0016, 0x0064 },
+ { 0x0016, 0x0065 },
+ { 0x0016, 0x0066 },
+ { 0x0016, 0x0067 },
+ { 0x0016, 0x0068 },
+ { 0x0016, 0x0069 },
+ { 0x0016, 0x006a },
+ { 0x0016, 0x006b },
+ { 0x0016, 0x006c },
+ { 0x0016, 0x006d },
+ { 0x0016, 0x006e },
+ { 0x0016, 0x006f },
+ { 0x0016, 0x0070 },
+ { 0x0016, 0x0071 },
+ { 0x0016, 0x0072 },
+ { 0x0016, 0x0073 },
+ { 0x0016, 0x0074 },
+ { 0x0016, 0x0075 },
+ { 0x0016, 0x0076 },
+ { 0x0016, 0x0077 },
+ { 0x0016, 0x0078 },
+ { 0x0016, 0x0079 },
+ { 0x0016, 0x007a },
+ { 0x0016, 0x007b },
+ { 0x0016, 0x007c },
+ { 0x0016, 0x007d },
+ { 0x0016, 0x007e },
+ { 0x0016, 0x007f },
+ { 0x0016, 0x0080 },
+ { 0x0016, 0x0081 },
+ { 0x0016, 0x0082 },
+ { 0x0016, 0x0083 },
+ { 0x0016, 0x0084 },
+ { 0x0016, 0x0085 },
+ { 0x0016, 0x0086 },
+ { 0x0016, 0x0087 },
+ { 0x0016, 0x0088 },
+ { 0x0016, 0x0089 },
+ { 0x0016, 0x008a },
+ { 0x0016, 0x008b },
+ { 0x0016, 0x008c },
+ { 0x0016, 0x008d },
+ { 0x0016, 0x008e },
+ { 0x0016, 0x008f },
+ { 0x0016, 0x0090 },
+ { 0x0016, 0x0091 },
+ { 0x0016, 0x0092 },
+ { 0x0016, 0x0093 },
+ { 0x0016, 0x0094 },
+ { 0x0016, 0x0095 },
+ { 0x0016, 0x0096 },
+ { 0x0016, 0x0097 },
+ { 0x0016, 0x0098 },
+ { 0x0016, 0x0099 },
+ { 0x0016, 0x009a },
+ { 0x0016, 0x009b },
+ { 0x0016, 0x009c },
+ { 0x0016, 0x009d },
+ { 0x0016, 0x009e },
+ { 0x0016, 0x009f },
+ { 0x0016, 0x00a0 },
+ { 0x0016, 0x00a1 },
+ { 0x0016, 0x00a2 },
+ { 0x0016, 0x00a3 },
+ { 0x0016, 0x00a4 },
+ { 0x0016, 0x00a5 },
+ { 0x0016, 0x00a6 },
+ { 0x0016, 0x00a7 },
+ { 0x0016, 0x00a8 },
+ { 0x0016, 0x00a9 },
+ { 0x0016, 0x00aa },
+ { 0x0016, 0x00ab },
+ { 0x0016, 0x00ac },
+ { 0x0016, 0x00ad },
+ { 0x0016, 0x00ae },
+ { 0x0016, 0x00af },
+ { 0x0016, 0x00b0 },
+ { 0x0016, 0x00b1 },
+ { 0x0016, 0x00b2 },
+ { 0x0016, 0x00b3 },
+ { 0x0016, 0x00b4 },
+ { 0x0016, 0x00b5 },
+ { 0x0016, 0x00b6 },
+ { 0x0016, 0x00b7 },
+ { 0x0016, 0x00b8 },
+ { 0x0016, 0x00b9 },
+ { 0x0016, 0x00ba },
+ { 0x0016, 0x00bb },
+ { 0x0016, 0x00bc },
+ { 0x0016, 0x00bd },
+ { 0x0016, 0x00be },
+ { 0x0016, 0x00bf },
+ { 0x0016, 0x00c0 },
+ { 0x0016, 0x00c1 },
+ { 0x0016, 0x00c2 },
+ { 0x0016, 0x00c3 },
+ { 0x0016, 0x00c4 },
+ { 0x0016, 0x00c5 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc13[324][2] =
+ {
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0006, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x000a, 0x0005 },
+ { 0x000c, 0x0007 },
+ { 0x000e, 0x000b },
+ { 0x0010, 0x0011 },
+ { 0x0012, 0x002d },
+ { 0x0015, 0x0000 },
+ { 0x0014, 0x0035 },
+ { 0x0015, 0x0001 },
+ { 0x0015, 0x0002 },
+ { 0x0015, 0x0003 },
+ { 0x0015, 0x0004 },
+ { 0x0015, 0x0005 },
+ { 0x0004, 0x0008 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0006, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0009, 0x0006 },
+ { 0x000c, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x0010, 0x0012 },
+ { 0x0011, 0x001a },
+ { 0x0015, 0x0006 },
+ { 0x0015, 0x0007 },
+ { 0x0015, 0x0008 },
+ { 0x0015, 0x0009 },
+ { 0x0015, 0x000a },
+ { 0x0015, 0x000b },
+ { 0x0015, 0x000c },
+ { 0x0005, 0x0007 },
+ { 0x0004, 0x000b },
+ { 0x0004, 0x000c },
+ { 0x0005, 0x0008 },
+ { 0x0006, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x000a, 0x0006 },
+ { 0x000c, 0x0009 },
+ { 0x000e, 0x000c },
+ { 0x0010, 0x0013 },
+ { 0x0012, 0x002e },
+ { 0x0015, 0x000d },
+ { 0x0015, 0x000e },
+ { 0x0015, 0x000f },
+ { 0x0015, 0x0010 },
+ { 0x0015, 0x0011 },
+ { 0x0015, 0x0012 },
+ { 0x0015, 0x0013 },
+ { 0x0005, 0x0009 },
+ { 0x0004, 0x000d },
+ { 0x0005, 0x000a },
+ { 0x0006, 0x0007 },
+ { 0x0007, 0x0005 },
+ { 0x0009, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000d, 0x000a },
+ { 0x000f, 0x000e },
+ { 0x0010, 0x0014 },
+ { 0x0011, 0x001b },
+ { 0x0014, 0x0036 },
+ { 0x0015, 0x0014 },
+ { 0x0015, 0x0015 },
+ { 0x0015, 0x0016 },
+ { 0x0015, 0x0017 },
+ { 0x0015, 0x0018 },
+ { 0x0015, 0x0019 },
+ { 0x0006, 0x0008 },
+ { 0x0005, 0x000b },
+ { 0x0006, 0x0009 },
+ { 0x0007, 0x0006 },
+ { 0x0009, 0x0008 },
+ { 0x000a, 0x0007 },
+ { 0x000c, 0x000a },
+ { 0x000e, 0x000d },
+ { 0x0010, 0x0015 },
+ { 0x0011, 0x001c },
+ { 0x0013, 0x0053 },
+ { 0x0015, 0x001a },
+ { 0x0015, 0x001b },
+ { 0x0015, 0x001c },
+ { 0x0015, 0x001d },
+ { 0x0015, 0x001e },
+ { 0x0015, 0x001f },
+ { 0x0015, 0x0020 },
+ { 0x0008, 0x0008 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x0008 },
+ { 0x000c, 0x000b },
+ { 0x000d, 0x000b },
+ { 0x000f, 0x000f },
+ { 0x0010, 0x0016 },
+ { 0x0011, 0x001d },
+ { 0x0014, 0x0037 },
+ { 0x0015, 0x0021 },
+ { 0x0015, 0x0022 },
+ { 0x0015, 0x0023 },
+ { 0x0015, 0x0024 },
+ { 0x0015, 0x0025 },
+ { 0x0015, 0x0026 },
+ { 0x0015, 0x0027 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000b, 0x0009 },
+ { 0x000c, 0x000c },
+ { 0x000d, 0x000c },
+ { 0x000f, 0x0010 },
+ { 0x0010, 0x0017 },
+ { 0x0012, 0x002f },
+ { 0x0015, 0x0028 },
+ { 0x0015, 0x0029 },
+ { 0x0015, 0x002a },
+ { 0x0015, 0x002b },
+ { 0x0015, 0x002c },
+ { 0x0015, 0x002d },
+ { 0x0015, 0x002e },
+ { 0x0015, 0x002f },
+ { 0x0015, 0x0030 },
+ { 0x000c, 0x000d },
+ { 0x000c, 0x000e },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x000d },
+ { 0x000e, 0x000e },
+ { 0x000f, 0x0011 },
+ { 0x0010, 0x0018 },
+ { 0x0011, 0x001e },
+ { 0x0014, 0x0038 },
+ { 0x0015, 0x0031 },
+ { 0x0015, 0x0032 },
+ { 0x0015, 0x0033 },
+ { 0x0015, 0x0034 },
+ { 0x0015, 0x0035 },
+ { 0x0015, 0x0036 },
+ { 0x0015, 0x0037 },
+ { 0x0015, 0x0038 },
+ { 0x0015, 0x0039 },
+ { 0x000f, 0x0012 },
+ { 0x000e, 0x000f },
+ { 0x000e, 0x0010 },
+ { 0x000e, 0x0011 },
+ { 0x000f, 0x0013 },
+ { 0x0010, 0x0019 },
+ { 0x0011, 0x001f },
+ { 0x0013, 0x0054 },
+ { 0x0015, 0x003a },
+ { 0x0014, 0x0039 },
+ { 0x0015, 0x003b },
+ { 0x0015, 0x003c },
+ { 0x0015, 0x003d },
+ { 0x0015, 0x003e },
+ { 0x0015, 0x003f },
+ { 0x0015, 0x0040 },
+ { 0x0015, 0x0041 },
+ { 0x0015, 0x0042 },
+ { 0x0010, 0x001a },
+ { 0x000f, 0x0014 },
+ { 0x000f, 0x0015 },
+ { 0x0010, 0x001b },
+ { 0x0011, 0x0020 },
+ { 0x0012, 0x0030 },
+ { 0x0013, 0x0055 },
+ { 0x0015, 0x0043 },
+ { 0x0015, 0x0044 },
+ { 0x0014, 0x003a },
+ { 0x0015, 0x0045 },
+ { 0x0015, 0x0046 },
+ { 0x0015, 0x0047 },
+ { 0x0015, 0x0048 },
+ { 0x0015, 0x0049 },
+ { 0x0015, 0x004a },
+ { 0x0015, 0x004b },
+ { 0x0015, 0x004c },
+ { 0x0012, 0x0031 },
+ { 0x0011, 0x0021 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0012, 0x0032 },
+ { 0x0015, 0x004d },
+ { 0x0015, 0x004e },
+ { 0x0015, 0x004f },
+ { 0x0015, 0x0050 },
+ { 0x0015, 0x0051 },
+ { 0x0015, 0x0052 },
+ { 0x0015, 0x0053 },
+ { 0x0015, 0x0054 },
+ { 0x0015, 0x0055 },
+ { 0x0015, 0x0056 },
+ { 0x0015, 0x0057 },
+ { 0x0015, 0x0058 },
+ { 0x0015, 0x0059 },
+ { 0x0015, 0x005a },
+ { 0x0014, 0x003b },
+ { 0x0012, 0x0033 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0015, 0x005b },
+ { 0x0015, 0x005c },
+ { 0x0015, 0x005d },
+ { 0x0015, 0x005e },
+ { 0x0015, 0x005f },
+ { 0x0015, 0x0060 },
+ { 0x0015, 0x0061 },
+ { 0x0015, 0x0062 },
+ { 0x0015, 0x0063 },
+ { 0x0015, 0x0064 },
+ { 0x0015, 0x0065 },
+ { 0x0015, 0x0066 },
+ { 0x0015, 0x0067 },
+ { 0x0015, 0x0068 },
+ { 0x0015, 0x0069 },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x0014, 0x003e },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0014, 0x0047 },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0014, 0x0052 },
+ { 0x0014, 0x0053 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0014, 0x005e },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x0014, 0x006a },
+ { 0x0014, 0x006b },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x0014, 0x006f },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x0014, 0x009d },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc14[400][2] =
+ {
+ { 0x0005, 0x0007 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0006, 0x0006 },
+ { 0x0007, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000d, 0x000c },
+ { 0x000f, 0x0013 },
+ { 0x0010, 0x001b },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0014, 0x0006 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0004, 0x000c },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0006, 0x0007 },
+ { 0x0008, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000c, 0x000a },
+ { 0x000e, 0x000e },
+ { 0x000f, 0x0014 },
+ { 0x0011, 0x002a },
+ { 0x0012, 0x004a },
+ { 0x0013, 0x0084 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0005, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0004, 0x000e },
+ { 0x0005, 0x000d },
+ { 0x0006, 0x0008 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000c, 0x000b },
+ { 0x000e, 0x000f },
+ { 0x000f, 0x0015 },
+ { 0x0012, 0x004b },
+ { 0x0013, 0x0085 },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0005, 0x000e },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0006, 0x0009 },
+ { 0x0008, 0x0008 },
+ { 0x0009, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000d, 0x000d },
+ { 0x000e, 0x0010 },
+ { 0x0010, 0x001c },
+ { 0x0011, 0x002b },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0006, 0x000a },
+ { 0x0005, 0x0011 },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0007, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x000a, 0x0009 },
+ { 0x000c, 0x000c },
+ { 0x000e, 0x0011 },
+ { 0x000f, 0x0016 },
+ { 0x0010, 0x001d },
+ { 0x0012, 0x004c },
+ { 0x0014, 0x001c },
+ { 0x0014, 0x001d },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0014, 0x0020 },
+ { 0x0014, 0x0021 },
+ { 0x0014, 0x0022 },
+ { 0x0014, 0x0023 },
+ { 0x0007, 0x0009 },
+ { 0x0006, 0x000d },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000b, 0x000a },
+ { 0x000d, 0x000e },
+ { 0x000f, 0x0017 },
+ { 0x0011, 0x002c },
+ { 0x0010, 0x001e },
+ { 0x0014, 0x0024 },
+ { 0x0014, 0x0025 },
+ { 0x0014, 0x0026 },
+ { 0x0014, 0x0027 },
+ { 0x0014, 0x0028 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0009, 0x000a },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x000b },
+ { 0x000b, 0x000b },
+ { 0x000d, 0x000f },
+ { 0x000e, 0x0012 },
+ { 0x000f, 0x0018 },
+ { 0x0011, 0x002d },
+ { 0x0011, 0x002e },
+ { 0x0013, 0x0086 },
+ { 0x0014, 0x002d },
+ { 0x0014, 0x002e },
+ { 0x0014, 0x002f },
+ { 0x0014, 0x0030 },
+ { 0x0014, 0x0031 },
+ { 0x0014, 0x0032 },
+ { 0x0014, 0x0033 },
+ { 0x0014, 0x0034 },
+ { 0x000b, 0x000c },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x000d },
+ { 0x000c, 0x000d },
+ { 0x000d, 0x0010 },
+ { 0x000e, 0x0013 },
+ { 0x000f, 0x0019 },
+ { 0x0010, 0x001f },
+ { 0x0013, 0x0087 },
+ { 0x0014, 0x0035 },
+ { 0x0014, 0x0036 },
+ { 0x0013, 0x0088 },
+ { 0x0014, 0x0037 },
+ { 0x0014, 0x0038 },
+ { 0x0014, 0x0039 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x000d, 0x0011 },
+ { 0x000c, 0x000e },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x0012 },
+ { 0x000d, 0x0013 },
+ { 0x000e, 0x0014 },
+ { 0x0010, 0x0020 },
+ { 0x0010, 0x0021 },
+ { 0x0012, 0x004d },
+ { 0x0011, 0x002f },
+ { 0x0014, 0x003e },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0014, 0x0047 },
+ { 0x000f, 0x001a },
+ { 0x000e, 0x0015 },
+ { 0x000e, 0x0016 },
+ { 0x000e, 0x0017 },
+ { 0x000f, 0x001b },
+ { 0x0011, 0x0030 },
+ { 0x0011, 0x0031 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0013, 0x008b },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0010, 0x0022 },
+ { 0x0010, 0x0023 },
+ { 0x0010, 0x0024 },
+ { 0x0010, 0x0025 },
+ { 0x0011, 0x0032 },
+ { 0x0011, 0x0033 },
+ { 0x0012, 0x004e },
+ { 0x0012, 0x004f },
+ { 0x0014, 0x0052 },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0014, 0x0053 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0011, 0x0034 },
+ { 0x0011, 0x0035 },
+ { 0x0012, 0x0050 },
+ { 0x0012, 0x0051 },
+ { 0x0013, 0x008e },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0014, 0x005e },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x0014, 0x006a },
+ { 0x0012, 0x0052 },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0014, 0x006b },
+ { 0x0013, 0x0091 },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x0014, 0x006f },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x0013, 0x0092 },
+ { 0x0012, 0x0053 },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0013, 0x0093 },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x0014, 0x009d },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+ { 0x0014, 0x00a6 },
+ { 0x0014, 0x00a7 },
+ { 0x0014, 0x00a8 },
+ { 0x0014, 0x00a9 },
+ { 0x0014, 0x00aa },
+ { 0x0014, 0x00ab },
+ { 0x0014, 0x00ac },
+ { 0x0014, 0x00ad },
+ { 0x0014, 0x00ae },
+ { 0x0014, 0x00af },
+ { 0x0014, 0x00b0 },
+ { 0x0014, 0x00b1 },
+ { 0x0014, 0x00b2 },
+ { 0x0014, 0x00b3 },
+ { 0x0014, 0x00b4 },
+ { 0x0014, 0x00b5 },
+ { 0x0014, 0x00b6 },
+ { 0x0014, 0x00b7 },
+ { 0x0014, 0x00b8 },
+ { 0x0014, 0x00b9 },
+ { 0x0014, 0x00ba },
+ { 0x0014, 0x00bb },
+ { 0x0014, 0x00bc },
+ { 0x0014, 0x00bd },
+ { 0x0014, 0x00be },
+ { 0x0014, 0x00bf },
+ { 0x0014, 0x00c0 },
+ { 0x0014, 0x00c1 },
+ { 0x0014, 0x00c2 },
+ { 0x0014, 0x00c3 },
+ { 0x0014, 0x00c4 },
+ { 0x0014, 0x00c5 },
+ { 0x0014, 0x00c6 },
+ { 0x0014, 0x00c7 },
+ { 0x0014, 0x00c8 },
+ { 0x0014, 0x00c9 },
+ { 0x0014, 0x00ca },
+ { 0x0014, 0x00cb },
+ { 0x0014, 0x00cc },
+ { 0x0014, 0x00cd },
+ { 0x0014, 0x00ce },
+ { 0x0014, 0x00cf },
+ { 0x0014, 0x00d0 },
+ { 0x0014, 0x00d1 },
+ { 0x0014, 0x00d2 },
+ { 0x0014, 0x00d3 },
+ { 0x0014, 0x00d4 },
+ { 0x0014, 0x00d5 },
+ { 0x0014, 0x00d6 },
+ { 0x0014, 0x00d7 },
+ { 0x0014, 0x00d8 },
+ { 0x0014, 0x00d9 },
+ { 0x0014, 0x00da },
+ { 0x0014, 0x00db },
+ { 0x0014, 0x00dc },
+ { 0x0014, 0x00dd },
+ { 0x0014, 0x00de },
+ { 0x0014, 0x00df },
+ { 0x0014, 0x00e0 },
+ { 0x0014, 0x00e1 },
+ { 0x0014, 0x00e2 },
+ { 0x0014, 0x00e3 },
+ { 0x0014, 0x00e4 },
+ { 0x0014, 0x00e5 },
+ { 0x0014, 0x00e6 },
+ { 0x0014, 0x00e7 },
+ { 0x0014, 0x00e8 },
+ { 0x0014, 0x00e9 },
+ { 0x0014, 0x00ea },
+ { 0x0014, 0x00eb },
+ { 0x0014, 0x00ec },
+ { 0x0014, 0x00ed },
+ { 0x0014, 0x00ee },
+ { 0x0014, 0x00ef },
+ { 0x0014, 0x00f0 },
+ { 0x0014, 0x00f1 },
+ { 0x0014, 0x00f2 },
+ { 0x0014, 0x00f3 },
+ { 0x0014, 0x00f4 },
+ { 0x0014, 0x00f5 },
+ { 0x0014, 0x00f6 },
+ { 0x0014, 0x00f7 },
+ { 0x0014, 0x00f8 },
+ { 0x0014, 0x00f9 },
+ { 0x0014, 0x00fa },
+ { 0x0014, 0x00fb },
+ { 0x0014, 0x00fc },
+ { 0x0014, 0x00fd },
+ { 0x0014, 0x00fe },
+ { 0x0014, 0x00ff },
+ { 0x0014, 0x0100 },
+ { 0x0014, 0x0101 },
+ { 0x0014, 0x0102 },
+ { 0x0014, 0x0103 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc15[576][2] =
+ {
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0007, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0008 },
+ { 0x000b, 0x000b },
+ { 0x000d, 0x000e },
+ { 0x000e, 0x0011 },
+ { 0x000f, 0x001a },
+ { 0x0012, 0x006e },
+ { 0x0014, 0x0000 },
+ { 0x0013, 0x00cc },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0014, 0x0006 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0005, 0x000d },
+ { 0x0004, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0006, 0x000b },
+ { 0x0007, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x000a, 0x000a },
+ { 0x000c, 0x000c },
+ { 0x000d, 0x000f },
+ { 0x000f, 0x001b },
+ { 0x0011, 0x003d },
+ { 0x0011, 0x003e },
+ { 0x0013, 0x00cd },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0005, 0x0010 },
+ { 0x0004, 0x000e },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0011 },
+ { 0x0005, 0x0012 },
+ { 0x0006, 0x000c },
+ { 0x0007, 0x000a },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x000b },
+ { 0x000c, 0x000d },
+ { 0x000e, 0x0012 },
+ { 0x0010, 0x0027 },
+ { 0x0011, 0x003f },
+ { 0x0012, 0x006f },
+ { 0x0014, 0x0013 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0014, 0x001c },
+ { 0x0006, 0x000d },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0005, 0x0015 },
+ { 0x0006, 0x000e },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x000b },
+ { 0x0009, 0x000a },
+ { 0x000b, 0x000c },
+ { 0x000c, 0x000e },
+ { 0x000e, 0x0013 },
+ { 0x000f, 0x001c },
+ { 0x0011, 0x0040 },
+ { 0x0012, 0x0070 },
+ { 0x0014, 0x001d },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0014, 0x0020 },
+ { 0x0014, 0x0021 },
+ { 0x0014, 0x0022 },
+ { 0x0014, 0x0023 },
+ { 0x0014, 0x0024 },
+ { 0x0014, 0x0025 },
+ { 0x0014, 0x0026 },
+ { 0x0006, 0x000f },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0007, 0x000c },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000d, 0x0010 },
+ { 0x000e, 0x0014 },
+ { 0x0010, 0x0028 },
+ { 0x0011, 0x0041 },
+ { 0x0013, 0x00ce },
+ { 0x0014, 0x0027 },
+ { 0x0014, 0x0028 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0014, 0x002d },
+ { 0x0014, 0x002e },
+ { 0x0014, 0x002f },
+ { 0x0014, 0x0030 },
+ { 0x0007, 0x000d },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0008, 0x000c },
+ { 0x0009, 0x000c },
+ { 0x000b, 0x000e },
+ { 0x000c, 0x000f },
+ { 0x000e, 0x0015 },
+ { 0x0010, 0x0029 },
+ { 0x0011, 0x0042 },
+ { 0x0014, 0x0031 },
+ { 0x0014, 0x0032 },
+ { 0x0014, 0x0033 },
+ { 0x0014, 0x0034 },
+ { 0x0014, 0x0035 },
+ { 0x0014, 0x0036 },
+ { 0x0014, 0x0037 },
+ { 0x0014, 0x0038 },
+ { 0x0014, 0x0039 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0014, 0x003c },
+ { 0x0008, 0x000d },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0008, 0x000e },
+ { 0x0009, 0x000d },
+ { 0x0009, 0x000e },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x0010 },
+ { 0x000d, 0x0011 },
+ { 0x000f, 0x001d },
+ { 0x0010, 0x002a },
+ { 0x0011, 0x0043 },
+ { 0x0014, 0x003d },
+ { 0x0013, 0x00cf },
+ { 0x0014, 0x003e },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0014, 0x0047 },
+ { 0x0009, 0x000f },
+ { 0x0008, 0x000f },
+ { 0x0009, 0x0010 },
+ { 0x0009, 0x0011 },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x0010 },
+ { 0x000c, 0x0011 },
+ { 0x000d, 0x0012 },
+ { 0x000e, 0x0016 },
+ { 0x0010, 0x002b },
+ { 0x0011, 0x0044 },
+ { 0x0012, 0x0071 },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0014, 0x0052 },
+ { 0x0014, 0x0053 },
+ { 0x000b, 0x0011 },
+ { 0x000a, 0x000e },
+ { 0x000a, 0x000f },
+ { 0x000b, 0x0012 },
+ { 0x000b, 0x0013 },
+ { 0x000c, 0x0012 },
+ { 0x000d, 0x0013 },
+ { 0x000e, 0x0017 },
+ { 0x0010, 0x002c },
+ { 0x0012, 0x0072 },
+ { 0x0011, 0x0045 },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0014, 0x005e },
+ { 0x000c, 0x0013 },
+ { 0x000c, 0x0014 },
+ { 0x000c, 0x0015 },
+ { 0x000d, 0x0014 },
+ { 0x000d, 0x0015 },
+ { 0x000e, 0x0018 },
+ { 0x000f, 0x001e },
+ { 0x0010, 0x002d },
+ { 0x0011, 0x0046 },
+ { 0x0011, 0x0047 },
+ { 0x0011, 0x0048 },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x0014, 0x006a },
+ { 0x0014, 0x006b },
+ { 0x000e, 0x0019 },
+ { 0x000d, 0x0016 },
+ { 0x000d, 0x0017 },
+ { 0x000e, 0x001a },
+ { 0x000e, 0x001b },
+ { 0x000f, 0x001f },
+ { 0x0010, 0x002e },
+ { 0x0011, 0x0049 },
+ { 0x0012, 0x0073 },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x0014, 0x006f },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0010, 0x002f },
+ { 0x000f, 0x0020 },
+ { 0x0010, 0x0030 },
+ { 0x000f, 0x0021 },
+ { 0x0010, 0x0031 },
+ { 0x0011, 0x004a },
+ { 0x0011, 0x004b },
+ { 0x0012, 0x0074 },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x0013, 0x00d2 },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0012, 0x0075 },
+ { 0x0010, 0x0032 },
+ { 0x0010, 0x0033 },
+ { 0x0011, 0x004c },
+ { 0x0011, 0x004d },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0012, 0x0076 },
+ { 0x0013, 0x00d5 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0012, 0x0077 },
+ { 0x0012, 0x0078 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0013, 0x00d8 },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x0014, 0x009d },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+ { 0x0014, 0x00a6 },
+ { 0x0014, 0x00a7 },
+ { 0x0014, 0x00a8 },
+ { 0x0014, 0x00a9 },
+ { 0x0014, 0x00aa },
+ { 0x0014, 0x00ab },
+ { 0x0014, 0x00ac },
+ { 0x0014, 0x00ad },
+ { 0x0014, 0x00ae },
+ { 0x0014, 0x00af },
+ { 0x0012, 0x0079 },
+ { 0x0014, 0x00b0 },
+ { 0x0014, 0x00b1 },
+ { 0x0014, 0x00b2 },
+ { 0x0014, 0x00b3 },
+ { 0x0014, 0x00b4 },
+ { 0x0014, 0x00b5 },
+ { 0x0014, 0x00b6 },
+ { 0x0014, 0x00b7 },
+ { 0x0014, 0x00b8 },
+ { 0x0014, 0x00b9 },
+ { 0x0014, 0x00ba },
+ { 0x0014, 0x00bb },
+ { 0x0014, 0x00bc },
+ { 0x0014, 0x00bd },
+ { 0x0014, 0x00be },
+ { 0x0014, 0x00bf },
+ { 0x0014, 0x00c0 },
+ { 0x0014, 0x00c1 },
+ { 0x0014, 0x00c2 },
+ { 0x0014, 0x00c3 },
+ { 0x0014, 0x00c4 },
+ { 0x0014, 0x00c5 },
+ { 0x0014, 0x00c6 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0014, 0x00c7 },
+ { 0x0014, 0x00c8 },
+ { 0x0014, 0x00c9 },
+ { 0x0014, 0x00ca },
+ { 0x0014, 0x00cb },
+ { 0x0014, 0x00cc },
+ { 0x0014, 0x00cd },
+ { 0x0014, 0x00ce },
+ { 0x0014, 0x00cf },
+ { 0x0014, 0x00d0 },
+ { 0x0014, 0x00d1 },
+ { 0x0014, 0x00d2 },
+ { 0x0014, 0x00d3 },
+ { 0x0014, 0x00d4 },
+ { 0x0014, 0x00d5 },
+ { 0x0014, 0x00d6 },
+ { 0x0014, 0x00d7 },
+ { 0x0014, 0x00d8 },
+ { 0x0014, 0x00d9 },
+ { 0x0014, 0x00da },
+ { 0x0014, 0x00db },
+ { 0x0014, 0x00dc },
+ { 0x0014, 0x00dd },
+ { 0x0014, 0x00de },
+ { 0x0014, 0x00df },
+ { 0x0014, 0x00e0 },
+ { 0x0014, 0x00e1 },
+ { 0x0014, 0x00e2 },
+ { 0x0014, 0x00e3 },
+ { 0x0014, 0x00e4 },
+ { 0x0014, 0x00e5 },
+ { 0x0014, 0x00e6 },
+ { 0x0014, 0x00e7 },
+ { 0x0014, 0x00e8 },
+ { 0x0014, 0x00e9 },
+ { 0x0014, 0x00ea },
+ { 0x0014, 0x00eb },
+ { 0x0014, 0x00ec },
+ { 0x0014, 0x00ed },
+ { 0x0014, 0x00ee },
+ { 0x0014, 0x00ef },
+ { 0x0014, 0x00f0 },
+ { 0x0014, 0x00f1 },
+ { 0x0014, 0x00f2 },
+ { 0x0014, 0x00f3 },
+ { 0x0014, 0x00f4 },
+ { 0x0014, 0x00f5 },
+ { 0x0014, 0x00f6 },
+ { 0x0014, 0x00f7 },
+ { 0x0014, 0x00f8 },
+ { 0x0014, 0x00f9 },
+ { 0x0014, 0x00fa },
+ { 0x0014, 0x00fb },
+ { 0x0014, 0x00fc },
+ { 0x0014, 0x00fd },
+ { 0x0014, 0x00fe },
+ { 0x0014, 0x00ff },
+ { 0x0014, 0x0100 },
+ { 0x0014, 0x0101 },
+ { 0x0014, 0x0102 },
+ { 0x0014, 0x0103 },
+ { 0x0014, 0x0104 },
+ { 0x0014, 0x0105 },
+ { 0x0014, 0x0106 },
+ { 0x0014, 0x0107 },
+ { 0x0014, 0x0108 },
+ { 0x0014, 0x0109 },
+ { 0x0014, 0x010a },
+ { 0x0014, 0x010b },
+ { 0x0014, 0x010c },
+ { 0x0014, 0x010d },
+ { 0x0014, 0x010e },
+ { 0x0014, 0x010f },
+ { 0x0014, 0x0110 },
+ { 0x0014, 0x0111 },
+ { 0x0014, 0x0112 },
+ { 0x0014, 0x0113 },
+ { 0x0014, 0x0114 },
+ { 0x0014, 0x0115 },
+ { 0x0014, 0x0116 },
+ { 0x0014, 0x0117 },
+ { 0x0014, 0x0118 },
+ { 0x0014, 0x0119 },
+ { 0x0014, 0x011a },
+ { 0x0014, 0x011b },
+ { 0x0014, 0x011c },
+ { 0x0014, 0x011d },
+ { 0x0014, 0x011e },
+ { 0x0014, 0x011f },
+ { 0x0014, 0x0120 },
+ { 0x0014, 0x0121 },
+ { 0x0014, 0x0122 },
+ { 0x0014, 0x0123 },
+ { 0x0014, 0x0124 },
+ { 0x0014, 0x0125 },
+ { 0x0014, 0x0126 },
+ { 0x0014, 0x0127 },
+ { 0x0014, 0x0128 },
+ { 0x0014, 0x0129 },
+ { 0x0014, 0x012a },
+ { 0x0014, 0x012b },
+ { 0x0014, 0x012c },
+ { 0x0014, 0x012d },
+ { 0x0014, 0x012e },
+ { 0x0014, 0x012f },
+ { 0x0014, 0x0130 },
+ { 0x0014, 0x0131 },
+ { 0x0014, 0x0132 },
+ { 0x0014, 0x0133 },
+ { 0x0014, 0x0134 },
+ { 0x0014, 0x0135 },
+ { 0x0014, 0x0136 },
+ { 0x0014, 0x0137 },
+ { 0x0014, 0x0138 },
+ { 0x0014, 0x0139 },
+ { 0x0014, 0x013a },
+ { 0x0014, 0x013b },
+ { 0x0014, 0x013c },
+ { 0x0014, 0x013d },
+ { 0x0014, 0x013e },
+ { 0x0014, 0x013f },
+ { 0x0014, 0x0140 },
+ { 0x0014, 0x0141 },
+ { 0x0014, 0x0142 },
+ { 0x0014, 0x0143 },
+ { 0x0014, 0x0144 },
+ { 0x0014, 0x0145 },
+ { 0x0014, 0x0146 },
+ { 0x0014, 0x0147 },
+ { 0x0014, 0x0148 },
+ { 0x0014, 0x0149 },
+ { 0x0014, 0x014a },
+ { 0x0014, 0x014b },
+ { 0x0014, 0x014c },
+ { 0x0014, 0x014d },
+ { 0x0014, 0x014e },
+ { 0x0014, 0x014f },
+ { 0x0014, 0x0150 },
+ { 0x0014, 0x0151 },
+ { 0x0014, 0x0152 },
+ { 0x0014, 0x0153 },
+ { 0x0014, 0x0154 },
+ { 0x0014, 0x0155 },
+ { 0x0014, 0x0156 },
+ { 0x0014, 0x0157 },
+ { 0x0014, 0x0158 },
+ { 0x0014, 0x0159 },
+ { 0x0014, 0x015a },
+ { 0x0014, 0x015b },
+ { 0x0014, 0x015c },
+ { 0x0014, 0x015d },
+ { 0x0014, 0x015e },
+ { 0x0014, 0x015f },
+ { 0x0014, 0x0160 },
+ { 0x0014, 0x0161 },
+ { 0x0014, 0x0162 },
+ { 0x0014, 0x0163 },
+ { 0x0014, 0x0164 },
+ { 0x0014, 0x0165 },
+ { 0x0014, 0x0166 },
+ { 0x0014, 0x0167 },
+ { 0x0014, 0x0168 },
+ { 0x0014, 0x0169 },
+ { 0x0014, 0x016a },
+ { 0x0014, 0x016b },
+ { 0x0014, 0x016c },
+ { 0x0014, 0x016d },
+ { 0x0014, 0x016e },
+ { 0x0014, 0x016f },
+ { 0x0014, 0x0170 },
+ { 0x0014, 0x0171 },
+ { 0x0014, 0x0172 },
+ { 0x0014, 0x0173 },
+ { 0x0014, 0x0174 },
+ { 0x0014, 0x0175 },
+ { 0x0014, 0x0176 },
+ { 0x0014, 0x0177 },
+ { 0x0014, 0x0178 },
+ { 0x0014, 0x0179 },
+ { 0x0014, 0x017a },
+ { 0x0014, 0x017b },
+ { 0x0014, 0x017c },
+ { 0x0014, 0x017d },
+ { 0x0014, 0x017e },
+ { 0x0014, 0x017f },
+ { 0x0014, 0x0180 },
+ { 0x0014, 0x0181 },
+ { 0x0014, 0x0182 },
+ { 0x0014, 0x0183 },
+ { 0x0014, 0x0184 },
+ { 0x0014, 0x0185 },
+ { 0x0014, 0x0186 },
+ { 0x0014, 0x0187 },
+ { 0x0014, 0x0188 },
+ { 0x0014, 0x0189 },
+ { 0x0014, 0x018a },
+ { 0x0014, 0x018b },
+ { 0x0014, 0x018c },
+ { 0x0014, 0x018d },
+ { 0x0014, 0x018e },
+ { 0x0014, 0x018f },
+ { 0x0014, 0x0190 },
+ { 0x0014, 0x0191 },
+ { 0x0014, 0x0192 },
+ { 0x0014, 0x0193 },
+ { 0x0014, 0x0194 },
+ { 0x0014, 0x0195 },
+ { 0x0014, 0x0196 },
+ { 0x0014, 0x0197 },
+ { 0x0013, 0x00db },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc16[729][2] =
+ {
+ { 0x0006, 0x000d },
+ { 0x0005, 0x0010 },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x000b, 0x000d },
+ { 0x000c, 0x000e },
+ { 0x000e, 0x0016 },
+ { 0x0010, 0x002d },
+ { 0x0011, 0x0051 },
+ { 0x0012, 0x008c },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0014, 0x0006 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0005, 0x0011 },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0012 },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0007, 0x000c },
+ { 0x0008, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000b, 0x000e },
+ { 0x000d, 0x0010 },
+ { 0x000e, 0x0017 },
+ { 0x000f, 0x001c },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0006, 0x0013 },
+ { 0x0005, 0x0015 },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0005, 0x0018 },
+ { 0x0006, 0x0014 },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0009, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x0011 },
+ { 0x000f, 0x001d },
+ { 0x0011, 0x0052 },
+ { 0x0012, 0x008d },
+ { 0x0012, 0x008e },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0014, 0x001c },
+ { 0x0014, 0x001d },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0014, 0x0020 },
+ { 0x0014, 0x0021 },
+ { 0x0006, 0x0015 },
+ { 0x0005, 0x0019 },
+ { 0x0005, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0007, 0x000f },
+ { 0x0008, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x0010 },
+ { 0x000d, 0x0012 },
+ { 0x000f, 0x001e },
+ { 0x0012, 0x008f },
+ { 0x0014, 0x0022 },
+ { 0x0014, 0x0023 },
+ { 0x0014, 0x0024 },
+ { 0x0014, 0x0025 },
+ { 0x0014, 0x0026 },
+ { 0x0014, 0x0027 },
+ { 0x0014, 0x0028 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0014, 0x002d },
+ { 0x0014, 0x002e },
+ { 0x0006, 0x0018 },
+ { 0x0005, 0x001c },
+ { 0x0005, 0x001d },
+ { 0x0006, 0x0019 },
+ { 0x0006, 0x001a },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0008, 0x000d },
+ { 0x000a, 0x000e },
+ { 0x000b, 0x0010 },
+ { 0x000c, 0x0011 },
+ { 0x000e, 0x0018 },
+ { 0x0010, 0x002e },
+ { 0x0012, 0x0090 },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0014, 0x002f },
+ { 0x0014, 0x0030 },
+ { 0x0014, 0x0031 },
+ { 0x0014, 0x0032 },
+ { 0x0014, 0x0033 },
+ { 0x0014, 0x0034 },
+ { 0x0014, 0x0035 },
+ { 0x0014, 0x0036 },
+ { 0x0014, 0x0037 },
+ { 0x0014, 0x0038 },
+ { 0x0014, 0x0039 },
+ { 0x0007, 0x0012 },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0007, 0x0013 },
+ { 0x0007, 0x0014 },
+ { 0x0008, 0x000e },
+ { 0x0009, 0x000e },
+ { 0x000b, 0x0011 },
+ { 0x000c, 0x0012 },
+ { 0x000d, 0x0013 },
+ { 0x000e, 0x0019 },
+ { 0x0010, 0x002f },
+ { 0x0012, 0x0091 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x0014, 0x003e },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0007, 0x0015 },
+ { 0x0006, 0x001e },
+ { 0x0006, 0x001f },
+ { 0x0007, 0x0016 },
+ { 0x0007, 0x0017 },
+ { 0x0008, 0x000f },
+ { 0x0009, 0x000f },
+ { 0x000a, 0x000f },
+ { 0x000b, 0x0012 },
+ { 0x000d, 0x0014 },
+ { 0x000e, 0x001a },
+ { 0x000f, 0x001f },
+ { 0x0013, 0x010f },
+ { 0x0011, 0x0053 },
+ { 0x0014, 0x0047 },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0014, 0x0052 },
+ { 0x0014, 0x0053 },
+ { 0x0008, 0x0010 },
+ { 0x0007, 0x0018 },
+ { 0x0007, 0x0019 },
+ { 0x0008, 0x0011 },
+ { 0x0008, 0x0012 },
+ { 0x0009, 0x0010 },
+ { 0x000a, 0x0010 },
+ { 0x000b, 0x0013 },
+ { 0x000c, 0x0013 },
+ { 0x000e, 0x001b },
+ { 0x000f, 0x0020 },
+ { 0x0010, 0x0030 },
+ { 0x0012, 0x0092 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0014, 0x005e },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0009, 0x0011 },
+ { 0x0008, 0x0013 },
+ { 0x0009, 0x0012 },
+ { 0x0009, 0x0013 },
+ { 0x000a, 0x0011 },
+ { 0x000a, 0x0012 },
+ { 0x000b, 0x0014 },
+ { 0x000c, 0x0014 },
+ { 0x000d, 0x0015 },
+ { 0x000e, 0x001c },
+ { 0x000f, 0x0021 },
+ { 0x0013, 0x0110 },
+ { 0x0012, 0x0093 },
+ { 0x0012, 0x0094 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x0014, 0x006a },
+ { 0x0014, 0x006b },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x000b, 0x0015 },
+ { 0x000a, 0x0013 },
+ { 0x000a, 0x0014 },
+ { 0x000a, 0x0015 },
+ { 0x000b, 0x0016 },
+ { 0x000c, 0x0015 },
+ { 0x000d, 0x0016 },
+ { 0x000d, 0x0017 },
+ { 0x000f, 0x0022 },
+ { 0x0010, 0x0031 },
+ { 0x0012, 0x0095 },
+ { 0x0012, 0x0096 },
+ { 0x0014, 0x006f },
+ { 0x0013, 0x0111 },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x000c, 0x0016 },
+ { 0x000b, 0x0017 },
+ { 0x000c, 0x0017 },
+ { 0x000c, 0x0018 },
+ { 0x000c, 0x0019 },
+ { 0x000d, 0x0018 },
+ { 0x000e, 0x001d },
+ { 0x000f, 0x0023 },
+ { 0x000f, 0x0024 },
+ { 0x0011, 0x0054 },
+ { 0x0012, 0x0097 },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x000e, 0x001e },
+ { 0x000d, 0x0019 },
+ { 0x000d, 0x001a },
+ { 0x000d, 0x001b },
+ { 0x000e, 0x001f },
+ { 0x000f, 0x0025 },
+ { 0x000f, 0x0026 },
+ { 0x0010, 0x0032 },
+ { 0x0010, 0x0033 },
+ { 0x0012, 0x0098 },
+ { 0x0013, 0x0112 },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x000f, 0x0027 },
+ { 0x000f, 0x0028 },
+ { 0x000f, 0x0029 },
+ { 0x000f, 0x002a },
+ { 0x0010, 0x0034 },
+ { 0x000f, 0x002b },
+ { 0x0011, 0x0055 },
+ { 0x0012, 0x0099 },
+ { 0x0012, 0x009a },
+ { 0x0012, 0x009b },
+ { 0x0014, 0x009d },
+ { 0x0013, 0x0113 },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+ { 0x0014, 0x00a6 },
+ { 0x0014, 0x00a7 },
+ { 0x0014, 0x00a8 },
+ { 0x0014, 0x00a9 },
+ { 0x0014, 0x00aa },
+ { 0x0014, 0x00ab },
+ { 0x0014, 0x00ac },
+ { 0x0011, 0x0056 },
+ { 0x0010, 0x0035 },
+ { 0x0010, 0x0036 },
+ { 0x0010, 0x0037 },
+ { 0x0011, 0x0057 },
+ { 0x0012, 0x009c },
+ { 0x0012, 0x009d },
+ { 0x0012, 0x009e },
+ { 0x0014, 0x00ad },
+ { 0x0014, 0x00ae },
+ { 0x0014, 0x00af },
+ { 0x0014, 0x00b0 },
+ { 0x0014, 0x00b1 },
+ { 0x0014, 0x00b2 },
+ { 0x0014, 0x00b3 },
+ { 0x0014, 0x00b4 },
+ { 0x0014, 0x00b5 },
+ { 0x0014, 0x00b6 },
+ { 0x0014, 0x00b7 },
+ { 0x0014, 0x00b8 },
+ { 0x0014, 0x00b9 },
+ { 0x0014, 0x00ba },
+ { 0x0014, 0x00bb },
+ { 0x0014, 0x00bc },
+ { 0x0014, 0x00bd },
+ { 0x0014, 0x00be },
+ { 0x0014, 0x00bf },
+ { 0x0012, 0x009f },
+ { 0x0011, 0x0058 },
+ { 0x0012, 0x00a0 },
+ { 0x0014, 0x00c0 },
+ { 0x0011, 0x0059 },
+ { 0x0013, 0x0114 },
+ { 0x0012, 0x00a1 },
+ { 0x0014, 0x00c1 },
+ { 0x0013, 0x0115 },
+ { 0x0014, 0x00c2 },
+ { 0x0014, 0x00c3 },
+ { 0x0014, 0x00c4 },
+ { 0x0014, 0x00c5 },
+ { 0x0014, 0x00c6 },
+ { 0x0014, 0x00c7 },
+ { 0x0014, 0x00c8 },
+ { 0x0014, 0x00c9 },
+ { 0x0014, 0x00ca },
+ { 0x0014, 0x00cb },
+ { 0x0014, 0x00cc },
+ { 0x0014, 0x00cd },
+ { 0x0014, 0x00ce },
+ { 0x0014, 0x00cf },
+ { 0x0014, 0x00d0 },
+ { 0x0014, 0x00d1 },
+ { 0x0014, 0x00d2 },
+ { 0x0014, 0x00d3 },
+ { 0x0014, 0x00d4 },
+ { 0x0014, 0x00d5 },
+ { 0x0014, 0x00d6 },
+ { 0x0014, 0x00d7 },
+ { 0x0014, 0x00d8 },
+ { 0x0014, 0x00d9 },
+ { 0x0014, 0x00da },
+ { 0x0014, 0x00db },
+ { 0x0014, 0x00dc },
+ { 0x0014, 0x00dd },
+ { 0x0014, 0x00de },
+ { 0x0014, 0x00df },
+ { 0x0014, 0x00e0 },
+ { 0x0014, 0x00e1 },
+ { 0x0014, 0x00e2 },
+ { 0x0014, 0x00e3 },
+ { 0x0014, 0x00e4 },
+ { 0x0014, 0x00e5 },
+ { 0x0014, 0x00e6 },
+ { 0x0014, 0x00e7 },
+ { 0x0014, 0x00e8 },
+ { 0x0014, 0x00e9 },
+ { 0x0014, 0x00ea },
+ { 0x0014, 0x00eb },
+ { 0x0014, 0x00ec },
+ { 0x0014, 0x00ed },
+ { 0x0014, 0x00ee },
+ { 0x0014, 0x00ef },
+ { 0x0014, 0x00f0 },
+ { 0x0014, 0x00f1 },
+ { 0x0014, 0x00f2 },
+ { 0x0014, 0x00f3 },
+ { 0x0014, 0x00f4 },
+ { 0x0014, 0x00f5 },
+ { 0x0014, 0x00f6 },
+ { 0x0014, 0x00f7 },
+ { 0x0014, 0x00f8 },
+ { 0x0014, 0x00f9 },
+ { 0x0014, 0x00fa },
+ { 0x0014, 0x00fb },
+ { 0x0014, 0x00fc },
+ { 0x0014, 0x00fd },
+ { 0x0014, 0x00fe },
+ { 0x0014, 0x00ff },
+ { 0x0014, 0x0100 },
+ { 0x0014, 0x0101 },
+ { 0x0014, 0x0102 },
+ { 0x0014, 0x0103 },
+ { 0x0014, 0x0104 },
+ { 0x0014, 0x0105 },
+ { 0x0014, 0x0106 },
+ { 0x0014, 0x0107 },
+ { 0x0014, 0x0108 },
+ { 0x0014, 0x0109 },
+ { 0x0014, 0x010a },
+ { 0x0014, 0x010b },
+ { 0x0014, 0x010c },
+ { 0x0014, 0x010d },
+ { 0x0014, 0x010e },
+ { 0x0014, 0x010f },
+ { 0x0014, 0x0110 },
+ { 0x0014, 0x0111 },
+ { 0x0014, 0x0112 },
+ { 0x0014, 0x0113 },
+ { 0x0014, 0x0114 },
+ { 0x0014, 0x0115 },
+ { 0x0014, 0x0116 },
+ { 0x0014, 0x0117 },
+ { 0x0014, 0x0118 },
+ { 0x0014, 0x0119 },
+ { 0x0014, 0x011a },
+ { 0x0014, 0x011b },
+ { 0x0014, 0x011c },
+ { 0x0014, 0x011d },
+ { 0x0014, 0x011e },
+ { 0x0014, 0x011f },
+ { 0x0014, 0x0120 },
+ { 0x0014, 0x0121 },
+ { 0x0014, 0x0122 },
+ { 0x0014, 0x0123 },
+ { 0x0014, 0x0124 },
+ { 0x0014, 0x0125 },
+ { 0x0013, 0x0116 },
+ { 0x0014, 0x0126 },
+ { 0x0014, 0x0127 },
+ { 0x0014, 0x0128 },
+ { 0x0014, 0x0129 },
+ { 0x0014, 0x012a },
+ { 0x0014, 0x012b },
+ { 0x0014, 0x012c },
+ { 0x0014, 0x012d },
+ { 0x0014, 0x012e },
+ { 0x0014, 0x012f },
+ { 0x0014, 0x0130 },
+ { 0x0014, 0x0131 },
+ { 0x0014, 0x0132 },
+ { 0x0014, 0x0133 },
+ { 0x0014, 0x0134 },
+ { 0x0014, 0x0135 },
+ { 0x0014, 0x0136 },
+ { 0x0014, 0x0137 },
+ { 0x0014, 0x0138 },
+ { 0x0014, 0x0139 },
+ { 0x0014, 0x013a },
+ { 0x0014, 0x013b },
+ { 0x0014, 0x013c },
+ { 0x0014, 0x013d },
+ { 0x0014, 0x013e },
+ { 0x0014, 0x013f },
+ { 0x0014, 0x0140 },
+ { 0x0014, 0x0141 },
+ { 0x0014, 0x0142 },
+ { 0x0014, 0x0143 },
+ { 0x0014, 0x0144 },
+ { 0x0014, 0x0145 },
+ { 0x0014, 0x0146 },
+ { 0x0014, 0x0147 },
+ { 0x0014, 0x0148 },
+ { 0x0014, 0x0149 },
+ { 0x0014, 0x014a },
+ { 0x0014, 0x014b },
+ { 0x0014, 0x014c },
+ { 0x0014, 0x014d },
+ { 0x0014, 0x014e },
+ { 0x0014, 0x014f },
+ { 0x0014, 0x0150 },
+ { 0x0014, 0x0151 },
+ { 0x0014, 0x0152 },
+ { 0x0014, 0x0153 },
+ { 0x0014, 0x0154 },
+ { 0x0014, 0x0155 },
+ { 0x0014, 0x0156 },
+ { 0x0014, 0x0157 },
+ { 0x0014, 0x0158 },
+ { 0x0014, 0x0159 },
+ { 0x0014, 0x015a },
+ { 0x0014, 0x015b },
+ { 0x0014, 0x015c },
+ { 0x0014, 0x015d },
+ { 0x0014, 0x015e },
+ { 0x0014, 0x015f },
+ { 0x0014, 0x0160 },
+ { 0x0014, 0x0161 },
+ { 0x0014, 0x0162 },
+ { 0x0014, 0x0163 },
+ { 0x0014, 0x0164 },
+ { 0x0014, 0x0165 },
+ { 0x0014, 0x0166 },
+ { 0x0014, 0x0167 },
+ { 0x0014, 0x0168 },
+ { 0x0014, 0x0169 },
+ { 0x0014, 0x016a },
+ { 0x0014, 0x016b },
+ { 0x0014, 0x016c },
+ { 0x0014, 0x016d },
+ { 0x0014, 0x016e },
+ { 0x0014, 0x016f },
+ { 0x0014, 0x0170 },
+ { 0x0014, 0x0171 },
+ { 0x0014, 0x0172 },
+ { 0x0014, 0x0173 },
+ { 0x0014, 0x0174 },
+ { 0x0014, 0x0175 },
+ { 0x0014, 0x0176 },
+ { 0x0014, 0x0177 },
+ { 0x0014, 0x0178 },
+ { 0x0014, 0x0179 },
+ { 0x0014, 0x017a },
+ { 0x0014, 0x017b },
+ { 0x0014, 0x017c },
+ { 0x0014, 0x017d },
+ { 0x0014, 0x017e },
+ { 0x0014, 0x017f },
+ { 0x0014, 0x0180 },
+ { 0x0014, 0x0181 },
+ { 0x0014, 0x0182 },
+ { 0x0014, 0x0183 },
+ { 0x0014, 0x0184 },
+ { 0x0014, 0x0185 },
+ { 0x0014, 0x0186 },
+ { 0x0014, 0x0187 },
+ { 0x0014, 0x0188 },
+ { 0x0014, 0x0189 },
+ { 0x0014, 0x018a },
+ { 0x0014, 0x018b },
+ { 0x0014, 0x018c },
+ { 0x0014, 0x018d },
+ { 0x0014, 0x018e },
+ { 0x0014, 0x018f },
+ { 0x0014, 0x0190 },
+ { 0x0014, 0x0191 },
+ { 0x0014, 0x0192 },
+ { 0x0014, 0x0193 },
+ { 0x0014, 0x0194 },
+ { 0x0014, 0x0195 },
+ { 0x0014, 0x0196 },
+ { 0x0014, 0x0197 },
+ { 0x0014, 0x0198 },
+ { 0x0014, 0x0199 },
+ { 0x0014, 0x019a },
+ { 0x0014, 0x019b },
+ { 0x0014, 0x019c },
+ { 0x0014, 0x019d },
+ { 0x0014, 0x019e },
+ { 0x0014, 0x019f },
+ { 0x0014, 0x01a0 },
+ { 0x0014, 0x01a1 },
+ { 0x0014, 0x01a2 },
+ { 0x0014, 0x01a3 },
+ { 0x0014, 0x01a4 },
+ { 0x0014, 0x01a5 },
+ { 0x0014, 0x01a6 },
+ { 0x0014, 0x01a7 },
+ { 0x0014, 0x01a8 },
+ { 0x0014, 0x01a9 },
+ { 0x0014, 0x01aa },
+ { 0x0014, 0x01ab },
+ { 0x0014, 0x01ac },
+ { 0x0014, 0x01ad },
+ { 0x0014, 0x01ae },
+ { 0x0014, 0x01af },
+ { 0x0014, 0x01b0 },
+ { 0x0014, 0x01b1 },
+ { 0x0014, 0x01b2 },
+ { 0x0014, 0x01b3 },
+ { 0x0014, 0x01b4 },
+ { 0x0014, 0x01b5 },
+ { 0x0014, 0x01b6 },
+ { 0x0014, 0x01b7 },
+ { 0x0014, 0x01b8 },
+ { 0x0014, 0x01b9 },
+ { 0x0014, 0x01ba },
+ { 0x0014, 0x01bb },
+ { 0x0014, 0x01bc },
+ { 0x0014, 0x01bd },
+ { 0x0014, 0x01be },
+ { 0x0014, 0x01bf },
+ { 0x0014, 0x01c0 },
+ { 0x0014, 0x01c1 },
+ { 0x0014, 0x01c2 },
+ { 0x0014, 0x01c3 },
+ { 0x0014, 0x01c4 },
+ { 0x0014, 0x01c5 },
+ { 0x0014, 0x01c6 },
+ { 0x0014, 0x01c7 },
+ { 0x0014, 0x01c8 },
+ { 0x0014, 0x01c9 },
+ { 0x0014, 0x01ca },
+ { 0x0014, 0x01cb },
+ { 0x0014, 0x01cc },
+ { 0x0014, 0x01cd },
+ { 0x0014, 0x01ce },
+ { 0x0014, 0x01cf },
+ { 0x0014, 0x01d0 },
+ { 0x0014, 0x01d1 },
+ { 0x0014, 0x01d2 },
+ { 0x0014, 0x01d3 },
+ { 0x0014, 0x01d4 },
+ { 0x0014, 0x01d5 },
+ { 0x0014, 0x01d6 },
+ { 0x0014, 0x01d7 },
+ { 0x0014, 0x01d8 },
+ { 0x0014, 0x01d9 },
+ { 0x0014, 0x01da },
+ { 0x0014, 0x01db },
+ { 0x0014, 0x01dc },
+ { 0x0014, 0x01dd },
+ { 0x0014, 0x01de },
+ { 0x0014, 0x01df },
+ { 0x0014, 0x01e0 },
+ { 0x0014, 0x01e1 },
+ { 0x0014, 0x01e2 },
+ { 0x0014, 0x01e3 },
+ { 0x0014, 0x01e4 },
+ { 0x0014, 0x01e5 },
+ { 0x0014, 0x01e6 },
+ { 0x0014, 0x01e7 },
+ { 0x0014, 0x01e8 },
+ { 0x0014, 0x01e9 },
+ { 0x0014, 0x01ea },
+ { 0x0014, 0x01eb },
+ { 0x0014, 0x01ec },
+ { 0x0014, 0x01ed },
+ { 0x0014, 0x01ee },
+ { 0x0014, 0x01ef },
+ { 0x0014, 0x01f0 },
+ { 0x0014, 0x01f1 },
+ { 0x0014, 0x01f2 },
+ { 0x0014, 0x01f3 },
+ { 0x0014, 0x01f4 },
+ { 0x0014, 0x01f5 },
+ { 0x0014, 0x01f6 },
+ { 0x0014, 0x01f7 },
+ { 0x0014, 0x01f8 },
+ { 0x0014, 0x01f9 },
+ { 0x0014, 0x01fa },
+ { 0x0014, 0x01fb },
+ { 0x0014, 0x01fc },
+ { 0x0014, 0x01fd },
+ { 0x0014, 0x01fe },
+ { 0x0014, 0x01ff },
+ { 0x0014, 0x0200 },
+ { 0x0014, 0x0201 },
+ { 0x0014, 0x0202 },
+ { 0x0014, 0x0203 },
+ { 0x0014, 0x0204 },
+ { 0x0014, 0x0205 },
+ { 0x0014, 0x0206 },
+ { 0x0014, 0x0207 },
+ { 0x0014, 0x0208 },
+ { 0x0014, 0x0209 },
+ { 0x0014, 0x020a },
+ { 0x0014, 0x020b },
+ { 0x0014, 0x020c },
+ { 0x0014, 0x020d },
+ { 0x0014, 0x020e },
+ { 0x0014, 0x020f },
+ { 0x0014, 0x0210 },
+ { 0x0014, 0x0211 },
+ { 0x0014, 0x0212 },
+ { 0x0014, 0x0213 },
+ { 0x0014, 0x0214 },
+ { 0x0014, 0x0215 },
+ { 0x0013, 0x0117 },
+
+ };
+
+
+const uint16_t c_aauiLCLDHuffEnc17[729][2] =
+ {
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0009, 0x000f },
+ { 0x000a, 0x000f },
+ { 0x000c, 0x0011 },
+ { 0x000d, 0x0014 },
+ { 0x000e, 0x0017 },
+ { 0x0010, 0x002d },
+ { 0x0011, 0x004c },
+ { 0x0012, 0x008a },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0014, 0x0006 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0006, 0x0016 },
+ { 0x0005, 0x0018 },
+ { 0x0005, 0x0019 },
+ { 0x0005, 0x001a },
+ { 0x0006, 0x0017 },
+ { 0x0006, 0x0018 },
+ { 0x0006, 0x0019 },
+ { 0x0007, 0x0012 },
+ { 0x0007, 0x0013 },
+ { 0x0008, 0x0010 },
+ { 0x000a, 0x0010 },
+ { 0x000b, 0x0011 },
+ { 0x000c, 0x0012 },
+ { 0x000e, 0x0018 },
+ { 0x000f, 0x0020 },
+ { 0x0011, 0x004d },
+ { 0x0013, 0x00e4 },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0006, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0005, 0x001c },
+ { 0x0005, 0x001d },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0007, 0x0014 },
+ { 0x0008, 0x0011 },
+ { 0x0009, 0x0010 },
+ { 0x000a, 0x0011 },
+ { 0x000b, 0x0012 },
+ { 0x000c, 0x0013 },
+ { 0x000e, 0x0019 },
+ { 0x000f, 0x0021 },
+ { 0x0010, 0x002e },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0014, 0x001c },
+ { 0x0006, 0x001e },
+ { 0x0005, 0x001e },
+ { 0x0005, 0x001f },
+ { 0x0006, 0x001f },
+ { 0x0006, 0x0020 },
+ { 0x0006, 0x0021 },
+ { 0x0006, 0x0022 },
+ { 0x0007, 0x0015 },
+ { 0x0008, 0x0012 },
+ { 0x0009, 0x0011 },
+ { 0x000a, 0x0012 },
+ { 0x000b, 0x0013 },
+ { 0x000c, 0x0014 },
+ { 0x000e, 0x001a },
+ { 0x000f, 0x0022 },
+ { 0x0010, 0x002f },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0014, 0x001d },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0014, 0x0020 },
+ { 0x0014, 0x0021 },
+ { 0x0014, 0x0022 },
+ { 0x0014, 0x0023 },
+ { 0x0014, 0x0024 },
+ { 0x0014, 0x0025 },
+ { 0x0006, 0x0023 },
+ { 0x0006, 0x0024 },
+ { 0x0006, 0x0025 },
+ { 0x0006, 0x0026 },
+ { 0x0006, 0x0027 },
+ { 0x0006, 0x0028 },
+ { 0x0007, 0x0016 },
+ { 0x0007, 0x0017 },
+ { 0x0008, 0x0013 },
+ { 0x0009, 0x0012 },
+ { 0x000a, 0x0013 },
+ { 0x000c, 0x0015 },
+ { 0x000d, 0x0015 },
+ { 0x000f, 0x0023 },
+ { 0x0010, 0x0030 },
+ { 0x0011, 0x004e },
+ { 0x0014, 0x0026 },
+ { 0x0014, 0x0027 },
+ { 0x0014, 0x0028 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0014, 0x002d },
+ { 0x0014, 0x002e },
+ { 0x0014, 0x002f },
+ { 0x0014, 0x0030 },
+ { 0x0007, 0x0018 },
+ { 0x0006, 0x0029 },
+ { 0x0006, 0x002a },
+ { 0x0006, 0x002b },
+ { 0x0006, 0x002c },
+ { 0x0007, 0x0019 },
+ { 0x0007, 0x001a },
+ { 0x0008, 0x0014 },
+ { 0x0009, 0x0013 },
+ { 0x000a, 0x0014 },
+ { 0x000b, 0x0014 },
+ { 0x000c, 0x0016 },
+ { 0x000d, 0x0016 },
+ { 0x000f, 0x0024 },
+ { 0x0010, 0x0031 },
+ { 0x0011, 0x004f },
+ { 0x0014, 0x0031 },
+ { 0x0014, 0x0032 },
+ { 0x0014, 0x0033 },
+ { 0x0014, 0x0034 },
+ { 0x0014, 0x0035 },
+ { 0x0014, 0x0036 },
+ { 0x0014, 0x0037 },
+ { 0x0014, 0x0038 },
+ { 0x0014, 0x0039 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0007, 0x001b },
+ { 0x0006, 0x002d },
+ { 0x0006, 0x002e },
+ { 0x0006, 0x002f },
+ { 0x0007, 0x001c },
+ { 0x0007, 0x001d },
+ { 0x0008, 0x0015 },
+ { 0x0009, 0x0014 },
+ { 0x000a, 0x0015 },
+ { 0x000a, 0x0016 },
+ { 0x000c, 0x0017 },
+ { 0x000d, 0x0017 },
+ { 0x000e, 0x001b },
+ { 0x000f, 0x0025 },
+ { 0x0011, 0x0050 },
+ { 0x0011, 0x0051 },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x0014, 0x003e },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0008, 0x0016 },
+ { 0x0007, 0x001e },
+ { 0x0007, 0x001f },
+ { 0x0007, 0x0020 },
+ { 0x0007, 0x0021 },
+ { 0x0008, 0x0017 },
+ { 0x0008, 0x0018 },
+ { 0x0009, 0x0015 },
+ { 0x000a, 0x0017 },
+ { 0x000b, 0x0015 },
+ { 0x000c, 0x0018 },
+ { 0x000e, 0x001c },
+ { 0x000e, 0x001d },
+ { 0x0010, 0x0032 },
+ { 0x0012, 0x008b },
+ { 0x0012, 0x008c },
+ { 0x0014, 0x0047 },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0008, 0x0019 },
+ { 0x0007, 0x0022 },
+ { 0x0007, 0x0023 },
+ { 0x0008, 0x001a },
+ { 0x0008, 0x001b },
+ { 0x0009, 0x0016 },
+ { 0x0009, 0x0017 },
+ { 0x000a, 0x0018 },
+ { 0x000b, 0x0016 },
+ { 0x000c, 0x0019 },
+ { 0x000d, 0x0018 },
+ { 0x000e, 0x001e },
+ { 0x0010, 0x0033 },
+ { 0x0011, 0x0052 },
+ { 0x0014, 0x0052 },
+ { 0x0013, 0x00e9 },
+ { 0x0014, 0x0053 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0009, 0x0018 },
+ { 0x0008, 0x001c },
+ { 0x0008, 0x001d },
+ { 0x0009, 0x0019 },
+ { 0x0009, 0x001a },
+ { 0x000a, 0x0019 },
+ { 0x000a, 0x001a },
+ { 0x000b, 0x0017 },
+ { 0x000c, 0x001a },
+ { 0x000d, 0x0019 },
+ { 0x000e, 0x001f },
+ { 0x000f, 0x0026 },
+ { 0x0010, 0x0034 },
+ { 0x0012, 0x008d },
+ { 0x0013, 0x00ea },
+ { 0x0014, 0x005e },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x000b, 0x0018 },
+ { 0x0009, 0x001b },
+ { 0x000a, 0x001b },
+ { 0x000a, 0x001c },
+ { 0x000a, 0x001d },
+ { 0x000b, 0x0019 },
+ { 0x000b, 0x001a },
+ { 0x000c, 0x001b },
+ { 0x000d, 0x001a },
+ { 0x000e, 0x0020 },
+ { 0x000f, 0x0027 },
+ { 0x0012, 0x008e },
+ { 0x0011, 0x0053 },
+ { 0x0013, 0x00eb },
+ { 0x0014, 0x006a },
+ { 0x0014, 0x006b },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x0014, 0x006f },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x000c, 0x001c },
+ { 0x000b, 0x001b },
+ { 0x000b, 0x001c },
+ { 0x000b, 0x001d },
+ { 0x000c, 0x001d },
+ { 0x000c, 0x001e },
+ { 0x000d, 0x001b },
+ { 0x000d, 0x001c },
+ { 0x000e, 0x0021 },
+ { 0x0010, 0x0035 },
+ { 0x0010, 0x0036 },
+ { 0x0011, 0x0054 },
+ { 0x0013, 0x00ec },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x000d, 0x001d },
+ { 0x000c, 0x001f },
+ { 0x000c, 0x0020 },
+ { 0x000c, 0x0021 },
+ { 0x000d, 0x001e },
+ { 0x000d, 0x001f },
+ { 0x000e, 0x0022 },
+ { 0x000f, 0x0028 },
+ { 0x0010, 0x0037 },
+ { 0x0010, 0x0038 },
+ { 0x0010, 0x0039 },
+ { 0x0012, 0x008f },
+ { 0x0013, 0x00ed },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x000e, 0x0023 },
+ { 0x000d, 0x0020 },
+ { 0x000d, 0x0021 },
+ { 0x000e, 0x0024 },
+ { 0x000e, 0x0025 },
+ { 0x000e, 0x0026 },
+ { 0x000f, 0x0029 },
+ { 0x0010, 0x003a },
+ { 0x0010, 0x003b },
+ { 0x0012, 0x0090 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x0014, 0x009d },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x000f, 0x002a },
+ { 0x000e, 0x0027 },
+ { 0x000f, 0x002b },
+ { 0x000f, 0x002c },
+ { 0x000f, 0x002d },
+ { 0x0010, 0x003c },
+ { 0x0010, 0x003d },
+ { 0x0011, 0x0055 },
+ { 0x0011, 0x0056 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+ { 0x0014, 0x00a6 },
+ { 0x0014, 0x00a7 },
+ { 0x0014, 0x00a8 },
+ { 0x0014, 0x00a9 },
+ { 0x0014, 0x00aa },
+ { 0x0014, 0x00ab },
+ { 0x0014, 0x00ac },
+ { 0x0014, 0x00ad },
+ { 0x0014, 0x00ae },
+ { 0x0014, 0x00af },
+ { 0x0014, 0x00b0 },
+ { 0x0014, 0x00b1 },
+ { 0x0014, 0x00b2 },
+ { 0x0014, 0x00b3 },
+ { 0x0014, 0x00b4 },
+ { 0x0014, 0x00b5 },
+ { 0x0012, 0x0091 },
+ { 0x0010, 0x003e },
+ { 0x0010, 0x003f },
+ { 0x0011, 0x0057 },
+ { 0x0011, 0x0058 },
+ { 0x0011, 0x0059 },
+ { 0x0012, 0x0092 },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0012, 0x0093 },
+ { 0x0014, 0x00b6 },
+ { 0x0014, 0x00b7 },
+ { 0x0014, 0x00b8 },
+ { 0x0014, 0x00b9 },
+ { 0x0014, 0x00ba },
+ { 0x0014, 0x00bb },
+ { 0x0014, 0x00bc },
+ { 0x0014, 0x00bd },
+ { 0x0014, 0x00be },
+ { 0x0014, 0x00bf },
+ { 0x0014, 0x00c0 },
+ { 0x0014, 0x00c1 },
+ { 0x0014, 0x00c2 },
+ { 0x0014, 0x00c3 },
+ { 0x0014, 0x00c4 },
+ { 0x0014, 0x00c5 },
+ { 0x0014, 0x00c6 },
+ { 0x0013, 0x00f0 },
+ { 0x0012, 0x0094 },
+ { 0x0012, 0x0095 },
+ { 0x0012, 0x0096 },
+ { 0x0014, 0x00c7 },
+ { 0x0014, 0x00c8 },
+ { 0x0014, 0x00c9 },
+ { 0x0014, 0x00ca },
+ { 0x0014, 0x00cb },
+ { 0x0014, 0x00cc },
+ { 0x0014, 0x00cd },
+ { 0x0014, 0x00ce },
+ { 0x0014, 0x00cf },
+ { 0x0014, 0x00d0 },
+ { 0x0014, 0x00d1 },
+ { 0x0014, 0x00d2 },
+ { 0x0014, 0x00d3 },
+ { 0x0014, 0x00d4 },
+ { 0x0014, 0x00d5 },
+ { 0x0014, 0x00d6 },
+ { 0x0014, 0x00d7 },
+ { 0x0014, 0x00d8 },
+ { 0x0014, 0x00d9 },
+ { 0x0014, 0x00da },
+ { 0x0014, 0x00db },
+ { 0x0014, 0x00dc },
+ { 0x0014, 0x00dd },
+ { 0x0014, 0x00de },
+ { 0x0012, 0x0097 },
+ { 0x0014, 0x00df },
+ { 0x0014, 0x00e0 },
+ { 0x0014, 0x00e1 },
+ { 0x0014, 0x00e2 },
+ { 0x0014, 0x00e3 },
+ { 0x0014, 0x00e4 },
+ { 0x0014, 0x00e5 },
+ { 0x0014, 0x00e6 },
+ { 0x0014, 0x00e7 },
+ { 0x0014, 0x00e8 },
+ { 0x0014, 0x00e9 },
+ { 0x0014, 0x00ea },
+ { 0x0014, 0x00eb },
+ { 0x0014, 0x00ec },
+ { 0x0014, 0x00ed },
+ { 0x0014, 0x00ee },
+ { 0x0014, 0x00ef },
+ { 0x0014, 0x00f0 },
+ { 0x0014, 0x00f1 },
+ { 0x0014, 0x00f2 },
+ { 0x0014, 0x00f3 },
+ { 0x0014, 0x00f4 },
+ { 0x0014, 0x00f5 },
+ { 0x0014, 0x00f6 },
+ { 0x0014, 0x00f7 },
+ { 0x0014, 0x00f8 },
+ { 0x0014, 0x00f9 },
+ { 0x0014, 0x00fa },
+ { 0x0014, 0x00fb },
+ { 0x0014, 0x00fc },
+ { 0x0014, 0x00fd },
+ { 0x0014, 0x00fe },
+ { 0x0014, 0x00ff },
+ { 0x0014, 0x0100 },
+ { 0x0014, 0x0101 },
+ { 0x0014, 0x0102 },
+ { 0x0014, 0x0103 },
+ { 0x0014, 0x0104 },
+ { 0x0014, 0x0105 },
+ { 0x0014, 0x0106 },
+ { 0x0014, 0x0107 },
+ { 0x0014, 0x0108 },
+ { 0x0014, 0x0109 },
+ { 0x0014, 0x010a },
+ { 0x0014, 0x010b },
+ { 0x0014, 0x010c },
+ { 0x0014, 0x010d },
+ { 0x0014, 0x010e },
+ { 0x0014, 0x010f },
+ { 0x0014, 0x0110 },
+ { 0x0014, 0x0111 },
+ { 0x0014, 0x0112 },
+ { 0x0014, 0x0113 },
+ { 0x0014, 0x0114 },
+ { 0x0014, 0x0115 },
+ { 0x0014, 0x0116 },
+ { 0x0014, 0x0117 },
+ { 0x0014, 0x0118 },
+ { 0x0014, 0x0119 },
+ { 0x0014, 0x011a },
+ { 0x0014, 0x011b },
+ { 0x0014, 0x011c },
+ { 0x0014, 0x011d },
+ { 0x0014, 0x011e },
+ { 0x0014, 0x011f },
+ { 0x0014, 0x0120 },
+ { 0x0014, 0x0121 },
+ { 0x0014, 0x0122 },
+ { 0x0014, 0x0123 },
+ { 0x0014, 0x0124 },
+ { 0x0014, 0x0125 },
+ { 0x0014, 0x0126 },
+ { 0x0014, 0x0127 },
+ { 0x0014, 0x0128 },
+ { 0x0014, 0x0129 },
+ { 0x0014, 0x012a },
+ { 0x0014, 0x012b },
+ { 0x0014, 0x012c },
+ { 0x0014, 0x012d },
+ { 0x0014, 0x012e },
+ { 0x0014, 0x012f },
+ { 0x0014, 0x0130 },
+ { 0x0014, 0x0131 },
+ { 0x0014, 0x0132 },
+ { 0x0014, 0x0133 },
+ { 0x0014, 0x0134 },
+ { 0x0014, 0x0135 },
+ { 0x0014, 0x0136 },
+ { 0x0014, 0x0137 },
+ { 0x0014, 0x0138 },
+ { 0x0014, 0x0139 },
+ { 0x0014, 0x013a },
+ { 0x0014, 0x013b },
+ { 0x0014, 0x013c },
+ { 0x0014, 0x013d },
+ { 0x0014, 0x013e },
+ { 0x0014, 0x013f },
+ { 0x0014, 0x0140 },
+ { 0x0014, 0x0141 },
+ { 0x0014, 0x0142 },
+ { 0x0014, 0x0143 },
+ { 0x0014, 0x0144 },
+ { 0x0014, 0x0145 },
+ { 0x0014, 0x0146 },
+ { 0x0014, 0x0147 },
+ { 0x0014, 0x0148 },
+ { 0x0014, 0x0149 },
+ { 0x0014, 0x014a },
+ { 0x0014, 0x014b },
+ { 0x0014, 0x014c },
+ { 0x0014, 0x014d },
+ { 0x0014, 0x014e },
+ { 0x0014, 0x014f },
+ { 0x0014, 0x0150 },
+ { 0x0014, 0x0151 },
+ { 0x0014, 0x0152 },
+ { 0x0014, 0x0153 },
+ { 0x0014, 0x0154 },
+ { 0x0014, 0x0155 },
+ { 0x0014, 0x0156 },
+ { 0x0014, 0x0157 },
+ { 0x0014, 0x0158 },
+ { 0x0014, 0x0159 },
+ { 0x0014, 0x015a },
+ { 0x0014, 0x015b },
+ { 0x0014, 0x015c },
+ { 0x0014, 0x015d },
+ { 0x0014, 0x015e },
+ { 0x0014, 0x015f },
+ { 0x0014, 0x0160 },
+ { 0x0014, 0x0161 },
+ { 0x0014, 0x0162 },
+ { 0x0014, 0x0163 },
+ { 0x0014, 0x0164 },
+ { 0x0014, 0x0165 },
+ { 0x0014, 0x0166 },
+ { 0x0014, 0x0167 },
+ { 0x0014, 0x0168 },
+ { 0x0014, 0x0169 },
+ { 0x0014, 0x016a },
+ { 0x0014, 0x016b },
+ { 0x0014, 0x016c },
+ { 0x0014, 0x016d },
+ { 0x0014, 0x016e },
+ { 0x0014, 0x016f },
+ { 0x0014, 0x0170 },
+ { 0x0014, 0x0171 },
+ { 0x0014, 0x0172 },
+ { 0x0014, 0x0173 },
+ { 0x0014, 0x0174 },
+ { 0x0014, 0x0175 },
+ { 0x0014, 0x0176 },
+ { 0x0014, 0x0177 },
+ { 0x0014, 0x0178 },
+ { 0x0014, 0x0179 },
+ { 0x0014, 0x017a },
+ { 0x0014, 0x017b },
+ { 0x0014, 0x017c },
+ { 0x0014, 0x017d },
+ { 0x0014, 0x017e },
+ { 0x0014, 0x017f },
+ { 0x0014, 0x0180 },
+ { 0x0014, 0x0181 },
+ { 0x0014, 0x0182 },
+ { 0x0014, 0x0183 },
+ { 0x0014, 0x0184 },
+ { 0x0014, 0x0185 },
+ { 0x0014, 0x0186 },
+ { 0x0014, 0x0187 },
+ { 0x0014, 0x0188 },
+ { 0x0014, 0x0189 },
+ { 0x0014, 0x018a },
+ { 0x0014, 0x018b },
+ { 0x0014, 0x018c },
+ { 0x0014, 0x018d },
+ { 0x0014, 0x018e },
+ { 0x0014, 0x018f },
+ { 0x0014, 0x0190 },
+ { 0x0014, 0x0191 },
+ { 0x0014, 0x0192 },
+ { 0x0014, 0x0193 },
+ { 0x0014, 0x0194 },
+ { 0x0014, 0x0195 },
+ { 0x0014, 0x0196 },
+ { 0x0014, 0x0197 },
+ { 0x0014, 0x0198 },
+ { 0x0014, 0x0199 },
+ { 0x0014, 0x019a },
+ { 0x0014, 0x019b },
+ { 0x0014, 0x019c },
+ { 0x0014, 0x019d },
+ { 0x0014, 0x019e },
+ { 0x0014, 0x019f },
+ { 0x0014, 0x01a0 },
+ { 0x0014, 0x01a1 },
+ { 0x0014, 0x01a2 },
+ { 0x0014, 0x01a3 },
+ { 0x0014, 0x01a4 },
+ { 0x0014, 0x01a5 },
+ { 0x0014, 0x01a6 },
+ { 0x0014, 0x01a7 },
+ { 0x0014, 0x01a8 },
+ { 0x0014, 0x01a9 },
+ { 0x0014, 0x01aa },
+ { 0x0014, 0x01ab },
+ { 0x0014, 0x01ac },
+ { 0x0014, 0x01ad },
+ { 0x0014, 0x01ae },
+ { 0x0014, 0x01af },
+ { 0x0014, 0x01b0 },
+ { 0x0014, 0x01b1 },
+ { 0x0014, 0x01b2 },
+ { 0x0014, 0x01b3 },
+ { 0x0014, 0x01b4 },
+ { 0x0014, 0x01b5 },
+ { 0x0014, 0x01b6 },
+ { 0x0014, 0x01b7 },
+ { 0x0014, 0x01b8 },
+ { 0x0014, 0x01b9 },
+ { 0x0014, 0x01ba },
+ { 0x0014, 0x01bb },
+ { 0x0014, 0x01bc },
+ { 0x0014, 0x01bd },
+ { 0x0014, 0x01be },
+ { 0x0014, 0x01bf },
+ { 0x0014, 0x01c0 },
+ { 0x0014, 0x01c1 },
+ { 0x0014, 0x01c2 },
+ { 0x0014, 0x01c3 },
+ { 0x0014, 0x01c4 },
+ { 0x0014, 0x01c5 },
+ { 0x0014, 0x01c6 },
+ { 0x0014, 0x01c7 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+ { 0x0013, 0x0110 },
+ { 0x0013, 0x0111 },
+ { 0x0013, 0x0112 },
+ { 0x0013, 0x0113 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc18[28][2] =
+ {
+ { 0x0004, 0x0001 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0002 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000f, 0x0001 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+
+ };
+
+
+const uint16_t c_aauiLCLDHuffEnc19[29][2] =
+ {
+ { 0x0004, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0003 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0005, 0x0001 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0006, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000f, 0x0001 },
+ { 0x0010, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0012, 0x0003 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc20[32][2] =
+ {
+ { 0x0004, 0x0002 },
+ { 0x0003, 0x0005 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0003 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0006, 0x0001 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000f, 0x0001 },
+ { 0x0010, 0x0001 },
+ { 0x0011, 0x0001 },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc21[37][2] =
+ {
+ { 0x0005, 0x0002 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0003 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0005, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0009, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000f, 0x0001 },
+ { 0x0010, 0x0001 },
+ { 0x0011, 0x0001 },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc22[39][2] =
+ {
+ { 0x0005, 0x0002 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0004, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0004, 0x000e },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000a, 0x0001 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000c, 0x0001 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000e, 0x0001 },
+ { 0x000e, 0x0002 },
+ { 0x000f, 0x0001 },
+ { 0x000e, 0x0003 },
+ { 0x0011, 0x0000 },
+ { 0x0010, 0x0001 },
+ { 0x0011, 0x0001 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc23[46][2] =
+ {
+ { 0x0005, 0x0003 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0004, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0004, 0x000e },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000e, 0x0001 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0001 },
+ { 0x0010, 0x0001 },
+ { 0x0012, 0x0000 },
+ { 0x0012, 0x0001 },
+ { 0x0011, 0x0001 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc24[55][2] =
+ {
+ { 0x0005, 0x0004 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0004, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0004, 0x000e },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0003 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0001 },
+ { 0x000f, 0x0002 },
+ { 0x000f, 0x0003 },
+ { 0x0010, 0x0001 },
+ { 0x0011, 0x0001 },
+ { 0x0013, 0x0000 },
+ { 0x0012, 0x0001 },
+ { 0x0013, 0x0001 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc25[65][2] =
+ {
+ { 0x0005, 0x0005 },
+ { 0x0004, 0x000c },
+ { 0x0004, 0x000d },
+ { 0x0004, 0x000e },
+ { 0x0005, 0x0006 },
+ { 0x0004, 0x000f },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0005, 0x0012 },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0005, 0x0015 },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000d, 0x0003 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000f, 0x0003 },
+ { 0x000e, 0x0005 },
+ { 0x000f, 0x0004 },
+ { 0x0010, 0x0001 },
+ { 0x000f, 0x0005 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0011, 0x0001 },
+ { 0x0012, 0x0000 },
+ { 0x0012, 0x0001 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc26[77][2] =
+ {
+ { 0x0006, 0x0004 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0005, 0x0012 },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0005, 0x0015 },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0005, 0x0018 },
+ { 0x0005, 0x0019 },
+ { 0x0005, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0005, 0x001c },
+ { 0x0005, 0x001d },
+ { 0x0005, 0x001e },
+ { 0x0005, 0x001f },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000a, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x000e, 0x0002 },
+ { 0x000d, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000f, 0x0003 },
+ { 0x000e, 0x0005 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0010, 0x0004 },
+ { 0x0011, 0x0002 },
+ { 0x0012, 0x0001 },
+ { 0x0010, 0x0005 },
+ { 0x0012, 0x0002 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0003 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+
+ };
+
+
+const uint16_t c_aauiLCLDHuffEnc27[91][2] =
+ {
+ { 0x0006, 0x0006 },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0005, 0x0012 },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0005, 0x0015 },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0005, 0x0018 },
+ { 0x0005, 0x0019 },
+ { 0x0005, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0005, 0x001c },
+ { 0x0005, 0x001d },
+ { 0x0005, 0x001e },
+ { 0x0005, 0x001f },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000e, 0x0006 },
+ { 0x000e, 0x0007 },
+ { 0x000f, 0x0003 },
+ { 0x000f, 0x0004 },
+ { 0x0010, 0x0003 },
+ { 0x000f, 0x0005 },
+ { 0x0012, 0x0000 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0011, 0x0004 },
+ { 0x0011, 0x0005 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc28[109][2] =
+ {
+ { 0x0006, 0x0008 },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0005, 0x0012 },
+ { 0x0005, 0x0013 },
+ { 0x0005, 0x0014 },
+ { 0x0005, 0x0015 },
+ { 0x0005, 0x0016 },
+ { 0x0005, 0x0017 },
+ { 0x0005, 0x0018 },
+ { 0x0005, 0x0019 },
+ { 0x0005, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0005, 0x001c },
+ { 0x0005, 0x001d },
+ { 0x0005, 0x001e },
+ { 0x0006, 0x0009 },
+ { 0x0005, 0x001f },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0006, 0x0018 },
+ { 0x0006, 0x0019 },
+ { 0x0006, 0x001a },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0006, 0x001e },
+ { 0x0006, 0x001f },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000e, 0x0006 },
+ { 0x000e, 0x0007 },
+ { 0x0010, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x0010, 0x0005 },
+ { 0x000f, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x0010, 0x0006 },
+ { 0x0011, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0013, 0x0000 },
+ { 0x0010, 0x0008 },
+ { 0x0010, 0x0009 },
+ { 0x0013, 0x0001 },
+ { 0x0011, 0x0007 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc29[129][2] =
+ {
+ { 0x0006, 0x0009 },
+ { 0x0005, 0x0019 },
+ { 0x0006, 0x000a },
+ { 0x0005, 0x001a },
+ { 0x0005, 0x001b },
+ { 0x0005, 0x001c },
+ { 0x0006, 0x000b },
+ { 0x0005, 0x001d },
+ { 0x0005, 0x001e },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0005, 0x001f },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0006, 0x0018 },
+ { 0x0006, 0x0019 },
+ { 0x0006, 0x001a },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0006, 0x001e },
+ { 0x0006, 0x001f },
+ { 0x0006, 0x0020 },
+ { 0x0006, 0x0021 },
+ { 0x0006, 0x0022 },
+ { 0x0006, 0x0023 },
+ { 0x0006, 0x0024 },
+ { 0x0006, 0x0025 },
+ { 0x0006, 0x0026 },
+ { 0x0006, 0x0027 },
+ { 0x0006, 0x0028 },
+ { 0x0006, 0x0029 },
+ { 0x0006, 0x002a },
+ { 0x0006, 0x002b },
+ { 0x0006, 0x002c },
+ { 0x0006, 0x002d },
+ { 0x0006, 0x002e },
+ { 0x0006, 0x002f },
+ { 0x0006, 0x0030 },
+ { 0x0006, 0x0031 },
+ { 0x0007, 0x0007 },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000e, 0x0006 },
+ { 0x000e, 0x0007 },
+ { 0x000e, 0x0008 },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x000f, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x0011, 0x0007 },
+ { 0x000f, 0x0008 },
+ { 0x0012, 0x0000 },
+ { 0x000f, 0x0009 },
+ { 0x0010, 0x0005 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x0012, 0x0001 },
+ { 0x0010, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0011, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+ { 0x0011, 0x0009 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc30[153][2] =
+ {
+ { 0x0007, 0x0009 },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0006, 0x0018 },
+ { 0x0006, 0x0019 },
+ { 0x0006, 0x001a },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0006, 0x001e },
+ { 0x0006, 0x001f },
+ { 0x0006, 0x0020 },
+ { 0x0006, 0x0021 },
+ { 0x0006, 0x0022 },
+ { 0x0006, 0x0023 },
+ { 0x0006, 0x0024 },
+ { 0x0006, 0x0025 },
+ { 0x0006, 0x0026 },
+ { 0x0006, 0x0027 },
+ { 0x0006, 0x0028 },
+ { 0x0006, 0x0029 },
+ { 0x0006, 0x002a },
+ { 0x0006, 0x002b },
+ { 0x0006, 0x002c },
+ { 0x0006, 0x002d },
+ { 0x0006, 0x002e },
+ { 0x0006, 0x002f },
+ { 0x0006, 0x0030 },
+ { 0x0006, 0x0031 },
+ { 0x0006, 0x0032 },
+ { 0x0006, 0x0033 },
+ { 0x0006, 0x0034 },
+ { 0x0006, 0x0035 },
+ { 0x0006, 0x0036 },
+ { 0x0006, 0x0037 },
+ { 0x0006, 0x0038 },
+ { 0x0006, 0x0039 },
+ { 0x0006, 0x003a },
+ { 0x0006, 0x003b },
+ { 0x0006, 0x003c },
+ { 0x0006, 0x003d },
+ { 0x0006, 0x003e },
+ { 0x0006, 0x003f },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0007, 0x0012 },
+ { 0x0007, 0x0013 },
+ { 0x0007, 0x0014 },
+ { 0x0007, 0x0015 },
+ { 0x0007, 0x0016 },
+ { 0x0007, 0x0017 },
+ { 0x0007, 0x0018 },
+ { 0x0007, 0x0019 },
+ { 0x0007, 0x001a },
+ { 0x0007, 0x001b },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0008, 0x0010 },
+ { 0x0008, 0x0011 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x0009, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x0009, 0x000e },
+ { 0x000a, 0x0008 },
+ { 0x0009, 0x000f },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000b, 0x000a },
+ { 0x000b, 0x000b },
+ { 0x000b, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000c, 0x0008 },
+ { 0x000b, 0x000e },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x0009 },
+ { 0x000c, 0x000a },
+ { 0x000d, 0x0008 },
+ { 0x000c, 0x000b },
+ { 0x000c, 0x000c },
+ { 0x000d, 0x0009 },
+ { 0x000c, 0x000d },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+ { 0x000e, 0x0008 },
+ { 0x000d, 0x000e },
+ { 0x000d, 0x000f },
+ { 0x000e, 0x0009 },
+ { 0x000e, 0x000a },
+ { 0x000e, 0x000b },
+ { 0x000e, 0x000c },
+ { 0x000f, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x000f, 0x0008 },
+ { 0x0010, 0x0006 },
+ { 0x000e, 0x000d },
+ { 0x000e, 0x000e },
+ { 0x000e, 0x000f },
+ { 0x0010, 0x0007 },
+ { 0x000f, 0x0009 },
+ { 0x0010, 0x0008 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x000f, 0x000c },
+ { 0x000f, 0x000d },
+ { 0x0010, 0x0009 },
+ { 0x0011, 0x0000 },
+ { 0x0011, 0x0001 },
+ { 0x0011, 0x0002 },
+ { 0x000f, 0x000e },
+ { 0x0010, 0x000a },
+ { 0x0011, 0x0003 },
+ { 0x0011, 0x0004 },
+ { 0x0011, 0x0005 },
+ { 0x000f, 0x000f },
+ { 0x0011, 0x0006 },
+ { 0x0011, 0x0007 },
+ { 0x0011, 0x0008 },
+ { 0x0011, 0x0009 },
+ { 0x0011, 0x000a },
+ { 0x0011, 0x000b },
+ { 0x0010, 0x000b },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc31[181][2] =
+ {
+ { 0x0007, 0x000b },
+ { 0x0006, 0x0015 },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0006, 0x0018 },
+ { 0x0006, 0x0019 },
+ { 0x0006, 0x001a },
+ { 0x0006, 0x001b },
+ { 0x0006, 0x001c },
+ { 0x0006, 0x001d },
+ { 0x0006, 0x001e },
+ { 0x0006, 0x001f },
+ { 0x0006, 0x0020 },
+ { 0x0006, 0x0021 },
+ { 0x0006, 0x0022 },
+ { 0x0006, 0x0023 },
+ { 0x0006, 0x0024 },
+ { 0x0006, 0x0025 },
+ { 0x0006, 0x0026 },
+ { 0x0006, 0x0027 },
+ { 0x0006, 0x0028 },
+ { 0x0006, 0x0029 },
+ { 0x0006, 0x002a },
+ { 0x0006, 0x002b },
+ { 0x0006, 0x002c },
+ { 0x0006, 0x002d },
+ { 0x0006, 0x002e },
+ { 0x0006, 0x002f },
+ { 0x0006, 0x0030 },
+ { 0x0006, 0x0031 },
+ { 0x0006, 0x0032 },
+ { 0x0006, 0x0033 },
+ { 0x0006, 0x0034 },
+ { 0x0006, 0x0035 },
+ { 0x0006, 0x0036 },
+ { 0x0006, 0x0037 },
+ { 0x0006, 0x0038 },
+ { 0x0006, 0x0039 },
+ { 0x0006, 0x003a },
+ { 0x0006, 0x003b },
+ { 0x0006, 0x003c },
+ { 0x0006, 0x003d },
+ { 0x0006, 0x003e },
+ { 0x0007, 0x000c },
+ { 0x0006, 0x003f },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0007, 0x0012 },
+ { 0x0007, 0x0013 },
+ { 0x0007, 0x0014 },
+ { 0x0007, 0x0015 },
+ { 0x0007, 0x0016 },
+ { 0x0007, 0x0017 },
+ { 0x0007, 0x0018 },
+ { 0x0007, 0x0019 },
+ { 0x0007, 0x001a },
+ { 0x0007, 0x001b },
+ { 0x0007, 0x001c },
+ { 0x0007, 0x001d },
+ { 0x0007, 0x001e },
+ { 0x0007, 0x001f },
+ { 0x0007, 0x0020 },
+ { 0x0007, 0x0021 },
+ { 0x0007, 0x0022 },
+ { 0x0007, 0x0023 },
+ { 0x0007, 0x0024 },
+ { 0x0007, 0x0025 },
+ { 0x0007, 0x0026 },
+ { 0x0007, 0x0027 },
+ { 0x0007, 0x0028 },
+ { 0x0007, 0x0029 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0008, 0x0010 },
+ { 0x0008, 0x0011 },
+ { 0x0008, 0x0012 },
+ { 0x0008, 0x0013 },
+ { 0x0008, 0x0014 },
+ { 0x0008, 0x0015 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x0009, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x0009, 0x000e },
+ { 0x0009, 0x000f },
+ { 0x0009, 0x0010 },
+ { 0x0009, 0x0011 },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000a, 0x000e },
+ { 0x000a, 0x000f },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000b, 0x000a },
+ { 0x000b, 0x000b },
+ { 0x000b, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000b, 0x000e },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000c, 0x000c },
+ { 0x000c, 0x000d },
+ { 0x000d, 0x0008 },
+ { 0x000c, 0x000e },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x000b },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+ { 0x000d, 0x000e },
+ { 0x000d, 0x000f },
+ { 0x000e, 0x0008 },
+ { 0x000e, 0x0009 },
+ { 0x000e, 0x000a },
+ { 0x000e, 0x000b },
+ { 0x000e, 0x000c },
+ { 0x000e, 0x000d },
+ { 0x000e, 0x000e },
+ { 0x000e, 0x000f },
+ { 0x000f, 0x0009 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x000f, 0x000c },
+ { 0x0010, 0x0009 },
+ { 0x000f, 0x000d },
+ { 0x000f, 0x000e },
+ { 0x0010, 0x000a },
+ { 0x0010, 0x000b },
+ { 0x0010, 0x000c },
+ { 0x0010, 0x000d },
+ { 0x0011, 0x000a },
+ { 0x0010, 0x000e },
+ { 0x000f, 0x000f },
+ { 0x0010, 0x000f },
+ { 0x0012, 0x0000 },
+ { 0x0012, 0x0001 },
+ { 0x0011, 0x000b },
+ { 0x0011, 0x000c },
+ { 0x0010, 0x0010 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0011, 0x000d },
+ { 0x0011, 0x000e },
+ { 0x0011, 0x000f },
+ { 0x0011, 0x0010 },
+ { 0x0011, 0x0011 },
+ { 0x0010, 0x0011 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+ { 0x0012, 0x000e },
+ { 0x0012, 0x000f },
+ { 0x0012, 0x0010 },
+ { 0x0012, 0x0011 },
+ { 0x0012, 0x0012 },
+ { 0x0012, 0x0013 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc33[16][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0008, 0x0000 },
+ { 0x0008, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc34[16][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0008, 0x0000 },
+ { 0x0008, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc35[25][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0007, 0x0006 },
+ { 0x0009, 0x0000 },
+ { 0x0009, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0007, 0x0007 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x0009, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc36[36][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0006, 0x0002 },
+ { 0x000b, 0x0000 },
+ { 0x000b, 0x0001 },
+ { 0x000b, 0x0002 },
+ { 0x0003, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0008, 0x0005 },
+ { 0x000b, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0003 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000b, 0x000a },
+ { 0x000b, 0x000b },
+ { 0x000b, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000b, 0x000e },
+ { 0x000b, 0x000f },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000a, 0x000e },
+ { 0x000a, 0x000f },
+ { 0x000a, 0x0010 },
+ { 0x000a, 0x0011 },
+ { 0x000a, 0x0012 },
+ { 0x000a, 0x0013 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc37[36][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000c, 0x0000 },
+ { 0x000c, 0x0001 },
+ { 0x000c, 0x0002 },
+ { 0x0003, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0006, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0007 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000c, 0x000c },
+ { 0x000c, 0x000d },
+ { 0x000c, 0x000e },
+ { 0x000c, 0x000f },
+ { 0x000c, 0x0010 },
+ { 0x000c, 0x0011 },
+ { 0x000c, 0x0012 },
+ { 0x000c, 0x0013 },
+ { 0x000c, 0x0014 },
+ { 0x000c, 0x0015 },
+ { 0x000c, 0x0016 },
+ { 0x000c, 0x0017 },
+ { 0x000c, 0x0018 },
+ { 0x000c, 0x0019 },
+ { 0x000b, 0x000d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc38[49][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000c, 0x0012 },
+ { 0x000d, 0x0000 },
+ { 0x000d, 0x0001 },
+ { 0x000d, 0x0002 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000b, 0x000a },
+ { 0x000d, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0009, 0x0003 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000c, 0x0013 },
+ { 0x000b, 0x000b },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+ { 0x000d, 0x000e },
+ { 0x000d, 0x000f },
+ { 0x000d, 0x0010 },
+ { 0x000d, 0x0011 },
+ { 0x000d, 0x0012 },
+ { 0x000d, 0x0013 },
+ { 0x000d, 0x0014 },
+ { 0x000d, 0x0015 },
+ { 0x000d, 0x0016 },
+ { 0x000d, 0x0017 },
+ { 0x000d, 0x0018 },
+ { 0x000d, 0x0019 },
+ { 0x000d, 0x001a },
+ { 0x000d, 0x001b },
+ { 0x000d, 0x001c },
+ { 0x000d, 0x001d },
+ { 0x000d, 0x001e },
+ { 0x000d, 0x001f },
+ { 0x000d, 0x0020 },
+ { 0x000d, 0x0021 },
+ { 0x000d, 0x0022 },
+ { 0x000d, 0x0023 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc39[64][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000a, 0x0002 },
+ { 0x000f, 0x0000 },
+ { 0x000f, 0x0001 },
+ { 0x000f, 0x0002 },
+ { 0x000f, 0x0003 },
+ { 0x0003, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0003 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x000f, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0009, 0x0003 },
+ { 0x000d, 0x000e },
+ { 0x000f, 0x0008 },
+ { 0x000f, 0x0009 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000d, 0x000f },
+ { 0x000f, 0x000c },
+ { 0x000f, 0x000d },
+ { 0x000f, 0x000e },
+ { 0x000f, 0x000f },
+ { 0x000f, 0x0010 },
+ { 0x000f, 0x0011 },
+ { 0x000f, 0x0012 },
+ { 0x000f, 0x0013 },
+ { 0x000f, 0x0014 },
+ { 0x000f, 0x0015 },
+ { 0x000f, 0x0016 },
+ { 0x000f, 0x0017 },
+ { 0x000f, 0x0018 },
+ { 0x000f, 0x0019 },
+ { 0x000f, 0x001a },
+ { 0x000f, 0x001b },
+ { 0x000f, 0x001c },
+ { 0x000f, 0x001d },
+ { 0x000f, 0x001e },
+ { 0x000f, 0x001f },
+ { 0x000f, 0x0020 },
+ { 0x000f, 0x0021 },
+ { 0x000f, 0x0022 },
+ { 0x000f, 0x0023 },
+ { 0x000f, 0x0024 },
+ { 0x000f, 0x0025 },
+ { 0x000f, 0x0026 },
+ { 0x000f, 0x0027 },
+ { 0x000f, 0x0028 },
+ { 0x000f, 0x0029 },
+ { 0x000e, 0x0015 },
+ { 0x000e, 0x0016 },
+ { 0x000e, 0x0017 },
+ { 0x000e, 0x0018 },
+ { 0x000e, 0x0019 },
+ { 0x000e, 0x001a },
+ { 0x000e, 0x001b },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc40[81][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0002, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000b, 0x0002 },
+ { 0x000f, 0x0011 },
+ { 0x0011, 0x0000 },
+ { 0x0011, 0x0001 },
+ { 0x0011, 0x0002 },
+ { 0x0011, 0x0003 },
+ { 0x0003, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0002 },
+ { 0x000e, 0x0009 },
+ { 0x0011, 0x0004 },
+ { 0x0011, 0x0005 },
+ { 0x0011, 0x0006 },
+ { 0x0011, 0x0007 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000d, 0x0005 },
+ { 0x0011, 0x0008 },
+ { 0x0011, 0x0009 },
+ { 0x0011, 0x000a },
+ { 0x0011, 0x000b },
+ { 0x0011, 0x000c },
+ { 0x000b, 0x0003 },
+ { 0x000a, 0x0003 },
+ { 0x000c, 0x0003 },
+ { 0x0011, 0x000d },
+ { 0x0011, 0x000e },
+ { 0x0011, 0x000f },
+ { 0x0011, 0x0010 },
+ { 0x0011, 0x0011 },
+ { 0x0011, 0x0012 },
+ { 0x0011, 0x0013 },
+ { 0x0011, 0x0014 },
+ { 0x0011, 0x0015 },
+ { 0x0011, 0x0016 },
+ { 0x0011, 0x0017 },
+ { 0x0011, 0x0018 },
+ { 0x0011, 0x0019 },
+ { 0x0011, 0x001a },
+ { 0x0011, 0x001b },
+ { 0x0011, 0x001c },
+ { 0x0011, 0x001d },
+ { 0x0011, 0x001e },
+ { 0x0011, 0x001f },
+ { 0x0011, 0x0020 },
+ { 0x0011, 0x0021 },
+ { 0x0011, 0x0022 },
+ { 0x0011, 0x0023 },
+ { 0x0011, 0x0024 },
+ { 0x0011, 0x0025 },
+ { 0x0011, 0x0026 },
+ { 0x0011, 0x0027 },
+ { 0x0011, 0x0028 },
+ { 0x0011, 0x0029 },
+ { 0x0011, 0x002a },
+ { 0x0011, 0x002b },
+ { 0x0011, 0x002c },
+ { 0x0011, 0x002d },
+ { 0x0011, 0x002e },
+ { 0x0011, 0x002f },
+ { 0x0011, 0x0030 },
+ { 0x0011, 0x0031 },
+ { 0x0011, 0x0032 },
+ { 0x0011, 0x0033 },
+ { 0x0011, 0x0034 },
+ { 0x0011, 0x0035 },
+ { 0x0011, 0x0036 },
+ { 0x0011, 0x0037 },
+ { 0x0011, 0x0038 },
+ { 0x0011, 0x0039 },
+ { 0x0011, 0x003a },
+ { 0x0011, 0x003b },
+ { 0x0010, 0x001e },
+ { 0x0010, 0x001f },
+ { 0x0010, 0x0020 },
+ { 0x0010, 0x0021 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc41[100][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x0011, 0x0014 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0002, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x0010, 0x000b },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x000d, 0x0002 },
+ { 0x0011, 0x0015 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000d, 0x0003 },
+ { 0x0010, 0x000c },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0010, 0x000d },
+ { 0x000f, 0x0007 },
+ { 0x0012, 0x0027 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc42[169][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000e, 0x0006 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0009, 0x0002 },
+ { 0x000d, 0x0004 },
+ { 0x0010, 0x0013 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0008, 0x0002 },
+ { 0x000b, 0x0002 },
+ { 0x000f, 0x000b },
+ { 0x0011, 0x0025 },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0009, 0x0003 },
+ { 0x0008, 0x0003 },
+ { 0x000b, 0x0003 },
+ { 0x000d, 0x0005 },
+ { 0x0010, 0x0014 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0007 },
+ { 0x0010, 0x0015 },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0012, 0x0045 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0012, 0x0046 },
+ { 0x0012, 0x0047 },
+ { 0x0012, 0x0048 },
+ { 0x0012, 0x0049 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc43[196][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0009, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x0010, 0x0017 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0009, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x0010, 0x0018 },
+ { 0x0012, 0x0050 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0008, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000d, 0x0004 },
+ { 0x0011, 0x002a },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0003 },
+ { 0x000c, 0x0005 },
+ { 0x000f, 0x000d },
+ { 0x0012, 0x0051 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0005 },
+ { 0x000f, 0x000e },
+ { 0x0011, 0x002b },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0011, 0x002c },
+ { 0x000f, 0x000f },
+ { 0x0010, 0x0019 },
+ { 0x0012, 0x0052 },
+ { 0x0012, 0x0053 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0011, 0x002d },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0013, 0x008b },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0013, 0x0095 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0013, 0x009c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc44[289][2] =
+ {
+ { 0x0001, 0x0001 },
+ { 0x0003, 0x0001 },
+ { 0x0006, 0x0002 },
+ { 0x0008, 0x0002 },
+ { 0x000b, 0x0002 },
+ { 0x000f, 0x000a },
+ { 0x0011, 0x0022 },
+ { 0x0014, 0x0000 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0014, 0x0006 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x000b, 0x0003 },
+ { 0x000e, 0x0007 },
+ { 0x0012, 0x003f },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0006, 0x0003 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0003 },
+ { 0x0009, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000f, 0x000b },
+ { 0x0012, 0x0040 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0014, 0x001c },
+ { 0x0014, 0x001d },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0009, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x0010, 0x0013 },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0014, 0x0020 },
+ { 0x0014, 0x0021 },
+ { 0x0014, 0x0022 },
+ { 0x0014, 0x0023 },
+ { 0x0014, 0x0024 },
+ { 0x0014, 0x0025 },
+ { 0x0014, 0x0026 },
+ { 0x0014, 0x0027 },
+ { 0x0014, 0x0028 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000e, 0x0008 },
+ { 0x0011, 0x0023 },
+ { 0x0012, 0x0041 },
+ { 0x0014, 0x0029 },
+ { 0x0014, 0x002a },
+ { 0x0013, 0x007b },
+ { 0x0014, 0x002b },
+ { 0x0014, 0x002c },
+ { 0x0014, 0x002d },
+ { 0x0014, 0x002e },
+ { 0x0014, 0x002f },
+ { 0x0014, 0x0030 },
+ { 0x0014, 0x0031 },
+ { 0x0014, 0x0032 },
+ { 0x000f, 0x000c },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x000d },
+ { 0x0011, 0x0024 },
+ { 0x0012, 0x0042 },
+ { 0x0014, 0x0033 },
+ { 0x0014, 0x0034 },
+ { 0x0014, 0x0035 },
+ { 0x0014, 0x0036 },
+ { 0x0014, 0x0037 },
+ { 0x0014, 0x0038 },
+ { 0x0014, 0x0039 },
+ { 0x0014, 0x003a },
+ { 0x0014, 0x003b },
+ { 0x0014, 0x003c },
+ { 0x0014, 0x003d },
+ { 0x0014, 0x003e },
+ { 0x0013, 0x007c },
+ { 0x0011, 0x0025 },
+ { 0x0012, 0x0043 },
+ { 0x0014, 0x003f },
+ { 0x0014, 0x0040 },
+ { 0x0014, 0x0041 },
+ { 0x0014, 0x0042 },
+ { 0x0014, 0x0043 },
+ { 0x0014, 0x0044 },
+ { 0x0014, 0x0045 },
+ { 0x0014, 0x0046 },
+ { 0x0014, 0x0047 },
+ { 0x0014, 0x0048 },
+ { 0x0014, 0x0049 },
+ { 0x0014, 0x004a },
+ { 0x0014, 0x004b },
+ { 0x0014, 0x004c },
+ { 0x0014, 0x004d },
+ { 0x0014, 0x004e },
+ { 0x0014, 0x004f },
+ { 0x0014, 0x0050 },
+ { 0x0014, 0x0051 },
+ { 0x0014, 0x0052 },
+ { 0x0014, 0x0053 },
+ { 0x0014, 0x0054 },
+ { 0x0014, 0x0055 },
+ { 0x0014, 0x0056 },
+ { 0x0014, 0x0057 },
+ { 0x0014, 0x0058 },
+ { 0x0014, 0x0059 },
+ { 0x0014, 0x005a },
+ { 0x0014, 0x005b },
+ { 0x0014, 0x005c },
+ { 0x0014, 0x005d },
+ { 0x0014, 0x005e },
+ { 0x0014, 0x005f },
+ { 0x0014, 0x0060 },
+ { 0x0014, 0x0061 },
+ { 0x0014, 0x0062 },
+ { 0x0014, 0x0063 },
+ { 0x0014, 0x0064 },
+ { 0x0014, 0x0065 },
+ { 0x0014, 0x0066 },
+ { 0x0014, 0x0067 },
+ { 0x0014, 0x0068 },
+ { 0x0014, 0x0069 },
+ { 0x0014, 0x006a },
+ { 0x0014, 0x006b },
+ { 0x0014, 0x006c },
+ { 0x0014, 0x006d },
+ { 0x0014, 0x006e },
+ { 0x0014, 0x006f },
+ { 0x0014, 0x0070 },
+ { 0x0014, 0x0071 },
+ { 0x0014, 0x0072 },
+ { 0x0014, 0x0073 },
+ { 0x0014, 0x0074 },
+ { 0x0014, 0x0075 },
+ { 0x0014, 0x0076 },
+ { 0x0014, 0x0077 },
+ { 0x0014, 0x0078 },
+ { 0x0014, 0x0079 },
+ { 0x0014, 0x007a },
+ { 0x0014, 0x007b },
+ { 0x0014, 0x007c },
+ { 0x0014, 0x007d },
+ { 0x0014, 0x007e },
+ { 0x0014, 0x007f },
+ { 0x0014, 0x0080 },
+ { 0x0014, 0x0081 },
+ { 0x0014, 0x0082 },
+ { 0x0014, 0x0083 },
+ { 0x0014, 0x0084 },
+ { 0x0014, 0x0085 },
+ { 0x0014, 0x0086 },
+ { 0x0014, 0x0087 },
+ { 0x0014, 0x0088 },
+ { 0x0014, 0x0089 },
+ { 0x0014, 0x008a },
+ { 0x0014, 0x008b },
+ { 0x0014, 0x008c },
+ { 0x0014, 0x008d },
+ { 0x0014, 0x008e },
+ { 0x0014, 0x008f },
+ { 0x0014, 0x0090 },
+ { 0x0014, 0x0091 },
+ { 0x0014, 0x0092 },
+ { 0x0014, 0x0093 },
+ { 0x0014, 0x0094 },
+ { 0x0014, 0x0095 },
+ { 0x0014, 0x0096 },
+ { 0x0014, 0x0097 },
+ { 0x0014, 0x0098 },
+ { 0x0014, 0x0099 },
+ { 0x0014, 0x009a },
+ { 0x0014, 0x009b },
+ { 0x0014, 0x009c },
+ { 0x0014, 0x009d },
+ { 0x0014, 0x009e },
+ { 0x0014, 0x009f },
+ { 0x0014, 0x00a0 },
+ { 0x0014, 0x00a1 },
+ { 0x0014, 0x00a2 },
+ { 0x0014, 0x00a3 },
+ { 0x0014, 0x00a4 },
+ { 0x0014, 0x00a5 },
+ { 0x0014, 0x00a6 },
+ { 0x0014, 0x00a7 },
+ { 0x0014, 0x00a8 },
+ { 0x0014, 0x00a9 },
+ { 0x0014, 0x00aa },
+ { 0x0014, 0x00ab },
+ { 0x0014, 0x00ac },
+ { 0x0014, 0x00ad },
+ { 0x0014, 0x00ae },
+ { 0x0014, 0x00af },
+ { 0x0014, 0x00b0 },
+ { 0x0014, 0x00b1 },
+ { 0x0014, 0x00b2 },
+ { 0x0014, 0x00b3 },
+ { 0x0014, 0x00b4 },
+ { 0x0014, 0x00b5 },
+ { 0x0014, 0x00b6 },
+ { 0x0014, 0x00b7 },
+ { 0x0014, 0x00b8 },
+ { 0x0014, 0x00b9 },
+ { 0x0014, 0x00ba },
+ { 0x0014, 0x00bb },
+ { 0x0014, 0x00bc },
+ { 0x0014, 0x00bd },
+ { 0x0014, 0x00be },
+ { 0x0014, 0x00bf },
+ { 0x0014, 0x00c0 },
+ { 0x0014, 0x00c1 },
+ { 0x0014, 0x00c2 },
+ { 0x0014, 0x00c3 },
+ { 0x0014, 0x00c4 },
+ { 0x0014, 0x00c5 },
+ { 0x0014, 0x00c6 },
+ { 0x0014, 0x00c7 },
+ { 0x0014, 0x00c8 },
+ { 0x0014, 0x00c9 },
+ { 0x0014, 0x00ca },
+ { 0x0014, 0x00cb },
+ { 0x0014, 0x00cc },
+ { 0x0014, 0x00cd },
+ { 0x0014, 0x00ce },
+ { 0x0014, 0x00cf },
+ { 0x0014, 0x00d0 },
+ { 0x0014, 0x00d1 },
+ { 0x0014, 0x00d2 },
+ { 0x0014, 0x00d3 },
+ { 0x0014, 0x00d4 },
+ { 0x0014, 0x00d5 },
+ { 0x0014, 0x00d6 },
+ { 0x0014, 0x00d7 },
+ { 0x0014, 0x00d8 },
+ { 0x0014, 0x00d9 },
+ { 0x0014, 0x00da },
+ { 0x0014, 0x00db },
+ { 0x0014, 0x00dc },
+ { 0x0014, 0x00dd },
+ { 0x0014, 0x00de },
+ { 0x0014, 0x00df },
+ { 0x0014, 0x00e0 },
+ { 0x0014, 0x00e1 },
+ { 0x0014, 0x00e2 },
+ { 0x0014, 0x00e3 },
+ { 0x0014, 0x00e4 },
+ { 0x0014, 0x00e5 },
+ { 0x0014, 0x00e6 },
+ { 0x0014, 0x00e7 },
+ { 0x0014, 0x00e8 },
+ { 0x0014, 0x00e9 },
+ { 0x0014, 0x00ea },
+ { 0x0014, 0x00eb },
+ { 0x0014, 0x00ec },
+ { 0x0014, 0x00ed },
+ { 0x0014, 0x00ee },
+ { 0x0014, 0x00ef },
+ { 0x0014, 0x00f0 },
+ { 0x0014, 0x00f1 },
+ { 0x0014, 0x00f2 },
+ { 0x0014, 0x00f3 },
+ { 0x0014, 0x00f4 },
+ { 0x0014, 0x00f5 },
+ { 0x0013, 0x007d },
+
+ };
+
+
+const uint16_t c_aauiLCLDHuffEnc45[324][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0003, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000c, 0x0005 },
+ { 0x0010, 0x0025 },
+ { 0x0012, 0x0088 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0006, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x000b, 0x0004 },
+ { 0x000f, 0x0014 },
+ { 0x0011, 0x0048 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0005, 0x0005 },
+ { 0x0004, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0007, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000d, 0x0007 },
+ { 0x000f, 0x0015 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0007, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0005 },
+ { 0x0009, 0x0005 },
+ { 0x000b, 0x0005 },
+ { 0x000d, 0x0008 },
+ { 0x0010, 0x0026 },
+ { 0x0012, 0x0089 },
+ { 0x0012, 0x008a },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000d, 0x0009 },
+ { 0x000f, 0x0016 },
+ { 0x0011, 0x0049 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x000c, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0007 },
+ { 0x000e, 0x000d },
+ { 0x0010, 0x0027 },
+ { 0x0012, 0x008b },
+ { 0x0012, 0x008c },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x000f, 0x0017 },
+ { 0x000f, 0x0018 },
+ { 0x000f, 0x0019 },
+ { 0x0012, 0x008d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0012, 0x008e },
+ { 0x0012, 0x008f },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0013, 0x008b },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0013, 0x0095 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0013, 0x009c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+ { 0x0013, 0x00a0 },
+ { 0x0013, 0x00a1 },
+ { 0x0013, 0x00a2 },
+ { 0x0013, 0x00a3 },
+ { 0x0013, 0x00a4 },
+ { 0x0013, 0x00a5 },
+ { 0x0013, 0x00a6 },
+ { 0x0013, 0x00a7 },
+ { 0x0013, 0x00a8 },
+ { 0x0013, 0x00a9 },
+ { 0x0013, 0x00aa },
+ { 0x0013, 0x00ab },
+ { 0x0013, 0x00ac },
+ { 0x0013, 0x00ad },
+ { 0x0013, 0x00ae },
+ { 0x0013, 0x00af },
+ { 0x0013, 0x00b0 },
+ { 0x0013, 0x00b1 },
+ { 0x0013, 0x00b2 },
+ { 0x0013, 0x00b3 },
+ { 0x0013, 0x00b4 },
+ { 0x0013, 0x00b5 },
+ { 0x0013, 0x00b6 },
+ { 0x0013, 0x00b7 },
+ { 0x0013, 0x00b8 },
+ { 0x0013, 0x00b9 },
+ { 0x0013, 0x00ba },
+ { 0x0013, 0x00bb },
+ { 0x0013, 0x00bc },
+ { 0x0013, 0x00bd },
+ { 0x0013, 0x00be },
+ { 0x0013, 0x00bf },
+ { 0x0013, 0x00c0 },
+ { 0x0013, 0x00c1 },
+ { 0x0013, 0x00c2 },
+ { 0x0013, 0x00c3 },
+ { 0x0013, 0x00c4 },
+ { 0x0013, 0x00c5 },
+ { 0x0013, 0x00c6 },
+ { 0x0013, 0x00c7 },
+ { 0x0013, 0x00c8 },
+ { 0x0013, 0x00c9 },
+ { 0x0013, 0x00ca },
+ { 0x0013, 0x00cb },
+ { 0x0013, 0x00cc },
+ { 0x0013, 0x00cd },
+ { 0x0013, 0x00ce },
+ { 0x0013, 0x00cf },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0013, 0x00d2 },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0013, 0x00d5 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0013, 0x00d8 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0013, 0x00db },
+ { 0x0013, 0x00dc },
+ { 0x0013, 0x00dd },
+ { 0x0013, 0x00de },
+ { 0x0013, 0x00df },
+ { 0x0013, 0x00e0 },
+ { 0x0013, 0x00e1 },
+ { 0x0013, 0x00e2 },
+ { 0x0013, 0x00e3 },
+ { 0x0013, 0x00e4 },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0013, 0x00e9 },
+ { 0x0013, 0x00ea },
+ { 0x0013, 0x00eb },
+ { 0x0013, 0x00ec },
+ { 0x0013, 0x00ed },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0013, 0x00f0 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc46[400][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0003, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000d, 0x000a },
+ { 0x000f, 0x0018 },
+ { 0x0012, 0x00a6 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0006, 0x0004 },
+ { 0x0008, 0x0004 },
+ { 0x000a, 0x0006 },
+ { 0x000c, 0x0008 },
+ { 0x000e, 0x0011 },
+ { 0x0012, 0x00a7 },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0007, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000d, 0x000b },
+ { 0x000f, 0x0019 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0007, 0x0006 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0005 },
+ { 0x000a, 0x0007 },
+ { 0x000c, 0x0009 },
+ { 0x000e, 0x0012 },
+ { 0x000f, 0x001a },
+ { 0x0012, 0x00a8 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0009, 0x0007 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000b, 0x0008 },
+ { 0x000d, 0x000c },
+ { 0x000e, 0x0013 },
+ { 0x0010, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x000b, 0x0009 },
+ { 0x000a, 0x0009 },
+ { 0x000b, 0x000a },
+ { 0x000b, 0x000b },
+ { 0x000d, 0x000d },
+ { 0x000f, 0x001b },
+ { 0x0010, 0x002d },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x000d, 0x000e },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000d, 0x000f },
+ { 0x000f, 0x001c },
+ { 0x000f, 0x001d },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x000f, 0x001e },
+ { 0x000f, 0x001f },
+ { 0x000f, 0x0020 },
+ { 0x000f, 0x0021 },
+ { 0x0010, 0x002e },
+ { 0x0012, 0x00a9 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0012, 0x00aa },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0010, 0x002f },
+ { 0x0013, 0x0062 },
+ { 0x0011, 0x0057 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0013, 0x008b },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0013, 0x0095 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0013, 0x009c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+ { 0x0013, 0x00a0 },
+ { 0x0013, 0x00a1 },
+ { 0x0013, 0x00a2 },
+ { 0x0013, 0x00a3 },
+ { 0x0013, 0x00a4 },
+ { 0x0013, 0x00a5 },
+ { 0x0013, 0x00a6 },
+ { 0x0013, 0x00a7 },
+ { 0x0013, 0x00a8 },
+ { 0x0013, 0x00a9 },
+ { 0x0013, 0x00aa },
+ { 0x0013, 0x00ab },
+ { 0x0013, 0x00ac },
+ { 0x0013, 0x00ad },
+ { 0x0013, 0x00ae },
+ { 0x0013, 0x00af },
+ { 0x0013, 0x00b0 },
+ { 0x0013, 0x00b1 },
+ { 0x0013, 0x00b2 },
+ { 0x0013, 0x00b3 },
+ { 0x0013, 0x00b4 },
+ { 0x0013, 0x00b5 },
+ { 0x0013, 0x00b6 },
+ { 0x0013, 0x00b7 },
+ { 0x0013, 0x00b8 },
+ { 0x0013, 0x00b9 },
+ { 0x0013, 0x00ba },
+ { 0x0013, 0x00bb },
+ { 0x0013, 0x00bc },
+ { 0x0013, 0x00bd },
+ { 0x0013, 0x00be },
+ { 0x0013, 0x00bf },
+ { 0x0013, 0x00c0 },
+ { 0x0013, 0x00c1 },
+ { 0x0013, 0x00c2 },
+ { 0x0013, 0x00c3 },
+ { 0x0013, 0x00c4 },
+ { 0x0013, 0x00c5 },
+ { 0x0013, 0x00c6 },
+ { 0x0013, 0x00c7 },
+ { 0x0013, 0x00c8 },
+ { 0x0013, 0x00c9 },
+ { 0x0013, 0x00ca },
+ { 0x0013, 0x00cb },
+ { 0x0013, 0x00cc },
+ { 0x0013, 0x00cd },
+ { 0x0013, 0x00ce },
+ { 0x0013, 0x00cf },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0013, 0x00d2 },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0013, 0x00d5 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0013, 0x00d8 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0013, 0x00db },
+ { 0x0013, 0x00dc },
+ { 0x0013, 0x00dd },
+ { 0x0013, 0x00de },
+ { 0x0013, 0x00df },
+ { 0x0013, 0x00e0 },
+ { 0x0013, 0x00e1 },
+ { 0x0013, 0x00e2 },
+ { 0x0013, 0x00e3 },
+ { 0x0013, 0x00e4 },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0013, 0x00e9 },
+ { 0x0013, 0x00ea },
+ { 0x0013, 0x00eb },
+ { 0x0013, 0x00ec },
+ { 0x0013, 0x00ed },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0013, 0x00f0 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+ { 0x0013, 0x0110 },
+ { 0x0013, 0x0111 },
+ { 0x0013, 0x0112 },
+ { 0x0013, 0x0113 },
+ { 0x0013, 0x0114 },
+ { 0x0013, 0x0115 },
+ { 0x0013, 0x0116 },
+ { 0x0013, 0x0117 },
+ { 0x0013, 0x0118 },
+ { 0x0013, 0x0119 },
+ { 0x0013, 0x011a },
+ { 0x0013, 0x011b },
+ { 0x0013, 0x011c },
+ { 0x0013, 0x011d },
+ { 0x0013, 0x011e },
+ { 0x0013, 0x011f },
+ { 0x0013, 0x0120 },
+ { 0x0013, 0x0121 },
+ { 0x0013, 0x0122 },
+ { 0x0013, 0x0123 },
+ { 0x0013, 0x0124 },
+ { 0x0013, 0x0125 },
+ { 0x0013, 0x0126 },
+ { 0x0013, 0x0127 },
+ { 0x0013, 0x0128 },
+ { 0x0013, 0x0129 },
+ { 0x0013, 0x012a },
+ { 0x0013, 0x012b },
+ { 0x0013, 0x012c },
+ { 0x0013, 0x012d },
+ { 0x0013, 0x012e },
+ { 0x0013, 0x012f },
+ { 0x0013, 0x0130 },
+ { 0x0013, 0x0131 },
+ { 0x0013, 0x0132 },
+ { 0x0013, 0x0133 },
+ { 0x0013, 0x0134 },
+ { 0x0013, 0x0135 },
+ { 0x0013, 0x0136 },
+ { 0x0013, 0x0137 },
+ { 0x0013, 0x0138 },
+ { 0x0013, 0x0139 },
+ { 0x0013, 0x013a },
+ { 0x0013, 0x013b },
+ { 0x0013, 0x013c },
+ { 0x0013, 0x013d },
+ { 0x0013, 0x013e },
+ { 0x0013, 0x013f },
+ { 0x0013, 0x0140 },
+ { 0x0013, 0x0141 },
+ { 0x0013, 0x0142 },
+ { 0x0013, 0x0143 },
+ { 0x0013, 0x0144 },
+ { 0x0013, 0x0145 },
+ { 0x0013, 0x0146 },
+ { 0x0013, 0x0147 },
+ { 0x0013, 0x0148 },
+ { 0x0013, 0x0149 },
+ { 0x0013, 0x014a },
+ { 0x0013, 0x014b },
+ { 0x0012, 0x00ab },
+ { 0x0012, 0x00ac },
+ { 0x0012, 0x00ad },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc47[576][2] =
+ {
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0005 },
+ { 0x0006, 0x0004 },
+ { 0x0008, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000c, 0x000b },
+ { 0x000d, 0x000d },
+ { 0x0010, 0x0041 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0004, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000d, 0x000e },
+ { 0x000f, 0x0025 },
+ { 0x000f, 0x0026 },
+ { 0x0012, 0x00f6 },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0005, 0x0006 },
+ { 0x0004, 0x0005 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0009, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000d, 0x000f },
+ { 0x000f, 0x0027 },
+ { 0x0012, 0x00f7 },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0007, 0x0006 },
+ { 0x0009, 0x0008 },
+ { 0x000a, 0x0008 },
+ { 0x000c, 0x000c },
+ { 0x000e, 0x0017 },
+ { 0x0010, 0x0042 },
+ { 0x0012, 0x00f8 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0008, 0x0008 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x0009 },
+ { 0x000b, 0x0009 },
+ { 0x000d, 0x0010 },
+ { 0x000f, 0x0028 },
+ { 0x000f, 0x0029 },
+ { 0x0011, 0x007f },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x000a, 0x000a },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x000b },
+ { 0x000b, 0x000a },
+ { 0x000d, 0x0011 },
+ { 0x000f, 0x002a },
+ { 0x0010, 0x0043 },
+ { 0x0012, 0x00f9 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x000b, 0x000b },
+ { 0x000b, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000c, 0x000d },
+ { 0x000d, 0x0012 },
+ { 0x000e, 0x0018 },
+ { 0x0010, 0x0044 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x000e, 0x0019 },
+ { 0x000d, 0x0013 },
+ { 0x000d, 0x0014 },
+ { 0x000d, 0x0015 },
+ { 0x000f, 0x002b },
+ { 0x0010, 0x0045 },
+ { 0x0013, 0x0066 },
+ { 0x0012, 0x00fa },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0010, 0x0046 },
+ { 0x000f, 0x002c },
+ { 0x000f, 0x002d },
+ { 0x0010, 0x0047 },
+ { 0x0011, 0x0080 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0010, 0x0048 },
+ { 0x0010, 0x0049 },
+ { 0x0011, 0x0081 },
+ { 0x0013, 0x008b },
+ { 0x0012, 0x00fb },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0013, 0x0095 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0013, 0x009c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+ { 0x0013, 0x00a0 },
+ { 0x0012, 0x00fc },
+ { 0x0013, 0x00a1 },
+ { 0x0013, 0x00a2 },
+ { 0x0013, 0x00a3 },
+ { 0x0013, 0x00a4 },
+ { 0x0013, 0x00a5 },
+ { 0x0013, 0x00a6 },
+ { 0x0013, 0x00a7 },
+ { 0x0013, 0x00a8 },
+ { 0x0013, 0x00a9 },
+ { 0x0013, 0x00aa },
+ { 0x0013, 0x00ab },
+ { 0x0013, 0x00ac },
+ { 0x0013, 0x00ad },
+ { 0x0013, 0x00ae },
+ { 0x0013, 0x00af },
+ { 0x0013, 0x00b0 },
+ { 0x0013, 0x00b1 },
+ { 0x0013, 0x00b2 },
+ { 0x0013, 0x00b3 },
+ { 0x0013, 0x00b4 },
+ { 0x0013, 0x00b5 },
+ { 0x0013, 0x00b6 },
+ { 0x0013, 0x00b7 },
+ { 0x0013, 0x00b8 },
+ { 0x0013, 0x00b9 },
+ { 0x0013, 0x00ba },
+ { 0x0013, 0x00bb },
+ { 0x0013, 0x00bc },
+ { 0x0013, 0x00bd },
+ { 0x0013, 0x00be },
+ { 0x0013, 0x00bf },
+ { 0x0013, 0x00c0 },
+ { 0x0013, 0x00c1 },
+ { 0x0013, 0x00c2 },
+ { 0x0013, 0x00c3 },
+ { 0x0013, 0x00c4 },
+ { 0x0013, 0x00c5 },
+ { 0x0013, 0x00c6 },
+ { 0x0013, 0x00c7 },
+ { 0x0013, 0x00c8 },
+ { 0x0013, 0x00c9 },
+ { 0x0013, 0x00ca },
+ { 0x0013, 0x00cb },
+ { 0x0013, 0x00cc },
+ { 0x0013, 0x00cd },
+ { 0x0013, 0x00ce },
+ { 0x0013, 0x00cf },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0013, 0x00d2 },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0013, 0x00d5 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0013, 0x00d8 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0013, 0x00db },
+ { 0x0013, 0x00dc },
+ { 0x0013, 0x00dd },
+ { 0x0013, 0x00de },
+ { 0x0013, 0x00df },
+ { 0x0013, 0x00e0 },
+ { 0x0013, 0x00e1 },
+ { 0x0013, 0x00e2 },
+ { 0x0013, 0x00e3 },
+ { 0x0013, 0x00e4 },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0013, 0x00e9 },
+ { 0x0013, 0x00ea },
+ { 0x0013, 0x00eb },
+ { 0x0013, 0x00ec },
+ { 0x0013, 0x00ed },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0013, 0x00f0 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+ { 0x0013, 0x0110 },
+ { 0x0013, 0x0111 },
+ { 0x0013, 0x0112 },
+ { 0x0013, 0x0113 },
+ { 0x0013, 0x0114 },
+ { 0x0013, 0x0115 },
+ { 0x0013, 0x0116 },
+ { 0x0013, 0x0117 },
+ { 0x0013, 0x0118 },
+ { 0x0013, 0x0119 },
+ { 0x0013, 0x011a },
+ { 0x0013, 0x011b },
+ { 0x0013, 0x011c },
+ { 0x0013, 0x011d },
+ { 0x0013, 0x011e },
+ { 0x0013, 0x011f },
+ { 0x0013, 0x0120 },
+ { 0x0013, 0x0121 },
+ { 0x0013, 0x0122 },
+ { 0x0013, 0x0123 },
+ { 0x0013, 0x0124 },
+ { 0x0013, 0x0125 },
+ { 0x0013, 0x0126 },
+ { 0x0013, 0x0127 },
+ { 0x0013, 0x0128 },
+ { 0x0013, 0x0129 },
+ { 0x0013, 0x012a },
+ { 0x0013, 0x012b },
+ { 0x0013, 0x012c },
+ { 0x0013, 0x012d },
+ { 0x0013, 0x012e },
+ { 0x0013, 0x012f },
+ { 0x0013, 0x0130 },
+ { 0x0013, 0x0131 },
+ { 0x0013, 0x0132 },
+ { 0x0013, 0x0133 },
+ { 0x0013, 0x0134 },
+ { 0x0013, 0x0135 },
+ { 0x0013, 0x0136 },
+ { 0x0013, 0x0137 },
+ { 0x0013, 0x0138 },
+ { 0x0013, 0x0139 },
+ { 0x0013, 0x013a },
+ { 0x0013, 0x013b },
+ { 0x0013, 0x013c },
+ { 0x0013, 0x013d },
+ { 0x0013, 0x013e },
+ { 0x0013, 0x013f },
+ { 0x0013, 0x0140 },
+ { 0x0013, 0x0141 },
+ { 0x0013, 0x0142 },
+ { 0x0013, 0x0143 },
+ { 0x0013, 0x0144 },
+ { 0x0013, 0x0145 },
+ { 0x0013, 0x0146 },
+ { 0x0013, 0x0147 },
+ { 0x0013, 0x0148 },
+ { 0x0013, 0x0149 },
+ { 0x0013, 0x014a },
+ { 0x0013, 0x014b },
+ { 0x0013, 0x014c },
+ { 0x0013, 0x014d },
+ { 0x0013, 0x014e },
+ { 0x0013, 0x014f },
+ { 0x0013, 0x0150 },
+ { 0x0013, 0x0151 },
+ { 0x0013, 0x0152 },
+ { 0x0013, 0x0153 },
+ { 0x0013, 0x0154 },
+ { 0x0013, 0x0155 },
+ { 0x0013, 0x0156 },
+ { 0x0013, 0x0157 },
+ { 0x0013, 0x0158 },
+ { 0x0013, 0x0159 },
+ { 0x0013, 0x015a },
+ { 0x0013, 0x015b },
+ { 0x0013, 0x015c },
+ { 0x0013, 0x015d },
+ { 0x0013, 0x015e },
+ { 0x0013, 0x015f },
+ { 0x0013, 0x0160 },
+ { 0x0013, 0x0161 },
+ { 0x0013, 0x0162 },
+ { 0x0013, 0x0163 },
+ { 0x0013, 0x0164 },
+ { 0x0013, 0x0165 },
+ { 0x0013, 0x0166 },
+ { 0x0013, 0x0167 },
+ { 0x0013, 0x0168 },
+ { 0x0013, 0x0169 },
+ { 0x0013, 0x016a },
+ { 0x0013, 0x016b },
+ { 0x0013, 0x016c },
+ { 0x0013, 0x016d },
+ { 0x0013, 0x016e },
+ { 0x0013, 0x016f },
+ { 0x0013, 0x0170 },
+ { 0x0013, 0x0171 },
+ { 0x0013, 0x0172 },
+ { 0x0013, 0x0173 },
+ { 0x0013, 0x0174 },
+ { 0x0013, 0x0175 },
+ { 0x0013, 0x0176 },
+ { 0x0013, 0x0177 },
+ { 0x0013, 0x0178 },
+ { 0x0013, 0x0179 },
+ { 0x0013, 0x017a },
+ { 0x0013, 0x017b },
+ { 0x0013, 0x017c },
+ { 0x0013, 0x017d },
+ { 0x0013, 0x017e },
+ { 0x0013, 0x017f },
+ { 0x0013, 0x0180 },
+ { 0x0013, 0x0181 },
+ { 0x0013, 0x0182 },
+ { 0x0013, 0x0183 },
+ { 0x0013, 0x0184 },
+ { 0x0013, 0x0185 },
+ { 0x0013, 0x0186 },
+ { 0x0013, 0x0187 },
+ { 0x0013, 0x0188 },
+ { 0x0013, 0x0189 },
+ { 0x0013, 0x018a },
+ { 0x0013, 0x018b },
+ { 0x0013, 0x018c },
+ { 0x0013, 0x018d },
+ { 0x0013, 0x018e },
+ { 0x0013, 0x018f },
+ { 0x0013, 0x0190 },
+ { 0x0013, 0x0191 },
+ { 0x0013, 0x0192 },
+ { 0x0013, 0x0193 },
+ { 0x0013, 0x0194 },
+ { 0x0013, 0x0195 },
+ { 0x0013, 0x0196 },
+ { 0x0013, 0x0197 },
+ { 0x0013, 0x0198 },
+ { 0x0013, 0x0199 },
+ { 0x0013, 0x019a },
+ { 0x0013, 0x019b },
+ { 0x0013, 0x019c },
+ { 0x0013, 0x019d },
+ { 0x0013, 0x019e },
+ { 0x0013, 0x019f },
+ { 0x0013, 0x01a0 },
+ { 0x0013, 0x01a1 },
+ { 0x0013, 0x01a2 },
+ { 0x0013, 0x01a3 },
+ { 0x0013, 0x01a4 },
+ { 0x0013, 0x01a5 },
+ { 0x0013, 0x01a6 },
+ { 0x0013, 0x01a7 },
+ { 0x0013, 0x01a8 },
+ { 0x0013, 0x01a9 },
+ { 0x0013, 0x01aa },
+ { 0x0013, 0x01ab },
+ { 0x0013, 0x01ac },
+ { 0x0013, 0x01ad },
+ { 0x0013, 0x01ae },
+ { 0x0013, 0x01af },
+ { 0x0013, 0x01b0 },
+ { 0x0013, 0x01b1 },
+ { 0x0013, 0x01b2 },
+ { 0x0013, 0x01b3 },
+ { 0x0013, 0x01b4 },
+ { 0x0013, 0x01b5 },
+ { 0x0013, 0x01b6 },
+ { 0x0013, 0x01b7 },
+ { 0x0013, 0x01b8 },
+ { 0x0013, 0x01b9 },
+ { 0x0013, 0x01ba },
+ { 0x0013, 0x01bb },
+ { 0x0013, 0x01bc },
+ { 0x0013, 0x01bd },
+ { 0x0013, 0x01be },
+ { 0x0013, 0x01bf },
+ { 0x0013, 0x01c0 },
+ { 0x0013, 0x01c1 },
+ { 0x0013, 0x01c2 },
+ { 0x0013, 0x01c3 },
+ { 0x0013, 0x01c4 },
+ { 0x0013, 0x01c5 },
+ { 0x0013, 0x01c6 },
+ { 0x0013, 0x01c7 },
+ { 0x0013, 0x01c8 },
+ { 0x0013, 0x01c9 },
+ { 0x0013, 0x01ca },
+ { 0x0013, 0x01cb },
+ { 0x0013, 0x01cc },
+ { 0x0013, 0x01cd },
+ { 0x0013, 0x01ce },
+ { 0x0013, 0x01cf },
+ { 0x0013, 0x01d0 },
+ { 0x0013, 0x01d1 },
+ { 0x0013, 0x01d2 },
+ { 0x0013, 0x01d3 },
+ { 0x0013, 0x01d4 },
+ { 0x0013, 0x01d5 },
+ { 0x0013, 0x01d6 },
+ { 0x0013, 0x01d7 },
+ { 0x0013, 0x01d8 },
+ { 0x0013, 0x01d9 },
+ { 0x0013, 0x01da },
+ { 0x0013, 0x01db },
+ { 0x0013, 0x01dc },
+ { 0x0013, 0x01dd },
+ { 0x0013, 0x01de },
+ { 0x0013, 0x01df },
+ { 0x0013, 0x01e0 },
+ { 0x0013, 0x01e1 },
+ { 0x0013, 0x01e2 },
+ { 0x0013, 0x01e3 },
+ { 0x0013, 0x01e4 },
+ { 0x0013, 0x01e5 },
+ { 0x0013, 0x01e6 },
+ { 0x0013, 0x01e7 },
+ { 0x0013, 0x01e8 },
+ { 0x0013, 0x01e9 },
+ { 0x0013, 0x01ea },
+ { 0x0013, 0x01eb },
+ { 0x0012, 0x00fd },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc48[729][2] =
+ {
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0006 },
+ { 0x0006, 0x0006 },
+ { 0x0008, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x000b, 0x000b },
+ { 0x000c, 0x000d },
+ { 0x000f, 0x0030 },
+ { 0x0010, 0x0055 },
+ { 0x0012, 0x0136 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0007 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000c, 0x000e },
+ { 0x000d, 0x0012 },
+ { 0x000f, 0x0031 },
+ { 0x0011, 0x00a0 },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0005, 0x0008 },
+ { 0x0004, 0x0005 },
+ { 0x0005, 0x0009 },
+ { 0x0006, 0x0008 },
+ { 0x0007, 0x0008 },
+ { 0x0008, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x0013 },
+ { 0x000f, 0x0032 },
+ { 0x0011, 0x00a1 },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0007, 0x0009 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0008 },
+ { 0x000b, 0x000c },
+ { 0x000d, 0x0014 },
+ { 0x000e, 0x001d },
+ { 0x000f, 0x0033 },
+ { 0x0012, 0x0137 },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0008, 0x000a },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x000b },
+ { 0x0009, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000c, 0x0010 },
+ { 0x000d, 0x0015 },
+ { 0x000f, 0x0034 },
+ { 0x0010, 0x0056 },
+ { 0x0012, 0x0138 },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0009, 0x000a },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x000b },
+ { 0x000c, 0x0011 },
+ { 0x000d, 0x0016 },
+ { 0x000e, 0x001e },
+ { 0x0010, 0x0057 },
+ { 0x0011, 0x00a2 },
+ { 0x0011, 0x00a3 },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x000b, 0x000d },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x000e },
+ { 0x000c, 0x0012 },
+ { 0x000d, 0x0017 },
+ { 0x000e, 0x001f },
+ { 0x0010, 0x0058 },
+ { 0x0012, 0x0139 },
+ { 0x0011, 0x00a4 },
+ { 0x0012, 0x013a },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x000c, 0x0013 },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x0014 },
+ { 0x000c, 0x0015 },
+ { 0x000d, 0x0018 },
+ { 0x000e, 0x0020 },
+ { 0x000f, 0x0035 },
+ { 0x0012, 0x013b },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x000e, 0x0021 },
+ { 0x000d, 0x0019 },
+ { 0x000e, 0x0022 },
+ { 0x000e, 0x0023 },
+ { 0x000f, 0x0036 },
+ { 0x0010, 0x0059 },
+ { 0x0011, 0x00a5 },
+ { 0x0013, 0x0083 },
+ { 0x0011, 0x00a6 },
+ { 0x0012, 0x013c },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x0013, 0x008b },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0010, 0x005a },
+ { 0x000f, 0x0037 },
+ { 0x000f, 0x0038 },
+ { 0x000f, 0x0039 },
+ { 0x0010, 0x005b },
+ { 0x0010, 0x005c },
+ { 0x0013, 0x0095 },
+ { 0x0011, 0x00a7 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0013, 0x009c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+ { 0x0013, 0x00a0 },
+ { 0x0013, 0x00a1 },
+ { 0x0013, 0x00a2 },
+ { 0x0013, 0x00a3 },
+ { 0x0013, 0x00a4 },
+ { 0x0013, 0x00a5 },
+ { 0x0013, 0x00a6 },
+ { 0x0013, 0x00a7 },
+ { 0x0013, 0x00a8 },
+ { 0x0010, 0x005d },
+ { 0x0010, 0x005e },
+ { 0x0013, 0x00a9 },
+ { 0x0010, 0x005f },
+ { 0x0013, 0x00aa },
+ { 0x0012, 0x013d },
+ { 0x0013, 0x00ab },
+ { 0x0013, 0x00ac },
+ { 0x0013, 0x00ad },
+ { 0x0013, 0x00ae },
+ { 0x0013, 0x00af },
+ { 0x0013, 0x00b0 },
+ { 0x0013, 0x00b1 },
+ { 0x0013, 0x00b2 },
+ { 0x0013, 0x00b3 },
+ { 0x0013, 0x00b4 },
+ { 0x0013, 0x00b5 },
+ { 0x0013, 0x00b6 },
+ { 0x0013, 0x00b7 },
+ { 0x0013, 0x00b8 },
+ { 0x0013, 0x00b9 },
+ { 0x0013, 0x00ba },
+ { 0x0013, 0x00bb },
+ { 0x0013, 0x00bc },
+ { 0x0013, 0x00bd },
+ { 0x0013, 0x00be },
+ { 0x0013, 0x00bf },
+ { 0x0013, 0x00c0 },
+ { 0x0011, 0x00a8 },
+ { 0x0013, 0x00c1 },
+ { 0x0011, 0x00a9 },
+ { 0x0013, 0x00c2 },
+ { 0x0013, 0x00c3 },
+ { 0x0013, 0x00c4 },
+ { 0x0013, 0x00c5 },
+ { 0x0013, 0x00c6 },
+ { 0x0013, 0x00c7 },
+ { 0x0013, 0x00c8 },
+ { 0x0013, 0x00c9 },
+ { 0x0013, 0x00ca },
+ { 0x0013, 0x00cb },
+ { 0x0013, 0x00cc },
+ { 0x0013, 0x00cd },
+ { 0x0013, 0x00ce },
+ { 0x0013, 0x00cf },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0013, 0x00d2 },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0013, 0x00d5 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0013, 0x00d8 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0012, 0x013e },
+ { 0x0013, 0x00db },
+ { 0x0013, 0x00dc },
+ { 0x0013, 0x00dd },
+ { 0x0013, 0x00de },
+ { 0x0013, 0x00df },
+ { 0x0013, 0x00e0 },
+ { 0x0013, 0x00e1 },
+ { 0x0013, 0x00e2 },
+ { 0x0013, 0x00e3 },
+ { 0x0013, 0x00e4 },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0013, 0x00e9 },
+ { 0x0013, 0x00ea },
+ { 0x0013, 0x00eb },
+ { 0x0013, 0x00ec },
+ { 0x0013, 0x00ed },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0013, 0x00f0 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+ { 0x0013, 0x0110 },
+ { 0x0013, 0x0111 },
+ { 0x0013, 0x0112 },
+ { 0x0013, 0x0113 },
+ { 0x0013, 0x0114 },
+ { 0x0013, 0x0115 },
+ { 0x0013, 0x0116 },
+ { 0x0013, 0x0117 },
+ { 0x0013, 0x0118 },
+ { 0x0013, 0x0119 },
+ { 0x0013, 0x011a },
+ { 0x0013, 0x011b },
+ { 0x0013, 0x011c },
+ { 0x0013, 0x011d },
+ { 0x0013, 0x011e },
+ { 0x0013, 0x011f },
+ { 0x0013, 0x0120 },
+ { 0x0013, 0x0121 },
+ { 0x0013, 0x0122 },
+ { 0x0013, 0x0123 },
+ { 0x0013, 0x0124 },
+ { 0x0013, 0x0125 },
+ { 0x0013, 0x0126 },
+ { 0x0013, 0x0127 },
+ { 0x0013, 0x0128 },
+ { 0x0013, 0x0129 },
+ { 0x0013, 0x012a },
+ { 0x0013, 0x012b },
+ { 0x0013, 0x012c },
+ { 0x0013, 0x012d },
+ { 0x0013, 0x012e },
+ { 0x0013, 0x012f },
+ { 0x0013, 0x0130 },
+ { 0x0013, 0x0131 },
+ { 0x0013, 0x0132 },
+ { 0x0013, 0x0133 },
+ { 0x0013, 0x0134 },
+ { 0x0013, 0x0135 },
+ { 0x0013, 0x0136 },
+ { 0x0013, 0x0137 },
+ { 0x0013, 0x0138 },
+ { 0x0013, 0x0139 },
+ { 0x0013, 0x013a },
+ { 0x0013, 0x013b },
+ { 0x0013, 0x013c },
+ { 0x0013, 0x013d },
+ { 0x0013, 0x013e },
+ { 0x0013, 0x013f },
+ { 0x0013, 0x0140 },
+ { 0x0013, 0x0141 },
+ { 0x0013, 0x0142 },
+ { 0x0013, 0x0143 },
+ { 0x0013, 0x0144 },
+ { 0x0013, 0x0145 },
+ { 0x0013, 0x0146 },
+ { 0x0013, 0x0147 },
+ { 0x0013, 0x0148 },
+ { 0x0013, 0x0149 },
+ { 0x0013, 0x014a },
+ { 0x0013, 0x014b },
+ { 0x0013, 0x014c },
+ { 0x0013, 0x014d },
+ { 0x0013, 0x014e },
+ { 0x0013, 0x014f },
+ { 0x0013, 0x0150 },
+ { 0x0013, 0x0151 },
+ { 0x0013, 0x0152 },
+ { 0x0013, 0x0153 },
+ { 0x0013, 0x0154 },
+ { 0x0013, 0x0155 },
+ { 0x0013, 0x0156 },
+ { 0x0013, 0x0157 },
+ { 0x0013, 0x0158 },
+ { 0x0013, 0x0159 },
+ { 0x0013, 0x015a },
+ { 0x0013, 0x015b },
+ { 0x0013, 0x015c },
+ { 0x0013, 0x015d },
+ { 0x0013, 0x015e },
+ { 0x0013, 0x015f },
+ { 0x0013, 0x0160 },
+ { 0x0013, 0x0161 },
+ { 0x0013, 0x0162 },
+ { 0x0013, 0x0163 },
+ { 0x0013, 0x0164 },
+ { 0x0013, 0x0165 },
+ { 0x0013, 0x0166 },
+ { 0x0013, 0x0167 },
+ { 0x0013, 0x0168 },
+ { 0x0013, 0x0169 },
+ { 0x0013, 0x016a },
+ { 0x0013, 0x016b },
+ { 0x0013, 0x016c },
+ { 0x0013, 0x016d },
+ { 0x0013, 0x016e },
+ { 0x0013, 0x016f },
+ { 0x0013, 0x0170 },
+ { 0x0013, 0x0171 },
+ { 0x0013, 0x0172 },
+ { 0x0013, 0x0173 },
+ { 0x0013, 0x0174 },
+ { 0x0013, 0x0175 },
+ { 0x0013, 0x0176 },
+ { 0x0013, 0x0177 },
+ { 0x0013, 0x0178 },
+ { 0x0013, 0x0179 },
+ { 0x0013, 0x017a },
+ { 0x0013, 0x017b },
+ { 0x0013, 0x017c },
+ { 0x0013, 0x017d },
+ { 0x0013, 0x017e },
+ { 0x0013, 0x017f },
+ { 0x0013, 0x0180 },
+ { 0x0013, 0x0181 },
+ { 0x0013, 0x0182 },
+ { 0x0013, 0x0183 },
+ { 0x0013, 0x0184 },
+ { 0x0013, 0x0185 },
+ { 0x0013, 0x0186 },
+ { 0x0013, 0x0187 },
+ { 0x0013, 0x0188 },
+ { 0x0013, 0x0189 },
+ { 0x0013, 0x018a },
+ { 0x0013, 0x018b },
+ { 0x0013, 0x018c },
+ { 0x0013, 0x018d },
+ { 0x0013, 0x018e },
+ { 0x0013, 0x018f },
+ { 0x0013, 0x0190 },
+ { 0x0013, 0x0191 },
+ { 0x0013, 0x0192 },
+ { 0x0013, 0x0193 },
+ { 0x0013, 0x0194 },
+ { 0x0013, 0x0195 },
+ { 0x0013, 0x0196 },
+ { 0x0013, 0x0197 },
+ { 0x0013, 0x0198 },
+ { 0x0013, 0x0199 },
+ { 0x0013, 0x019a },
+ { 0x0013, 0x019b },
+ { 0x0013, 0x019c },
+ { 0x0013, 0x019d },
+ { 0x0013, 0x019e },
+ { 0x0013, 0x019f },
+ { 0x0013, 0x01a0 },
+ { 0x0013, 0x01a1 },
+ { 0x0013, 0x01a2 },
+ { 0x0013, 0x01a3 },
+ { 0x0013, 0x01a4 },
+ { 0x0013, 0x01a5 },
+ { 0x0013, 0x01a6 },
+ { 0x0013, 0x01a7 },
+ { 0x0013, 0x01a8 },
+ { 0x0013, 0x01a9 },
+ { 0x0013, 0x01aa },
+ { 0x0013, 0x01ab },
+ { 0x0013, 0x01ac },
+ { 0x0013, 0x01ad },
+ { 0x0013, 0x01ae },
+ { 0x0013, 0x01af },
+ { 0x0013, 0x01b0 },
+ { 0x0013, 0x01b1 },
+ { 0x0013, 0x01b2 },
+ { 0x0013, 0x01b3 },
+ { 0x0013, 0x01b4 },
+ { 0x0013, 0x01b5 },
+ { 0x0013, 0x01b6 },
+ { 0x0013, 0x01b7 },
+ { 0x0013, 0x01b8 },
+ { 0x0013, 0x01b9 },
+ { 0x0013, 0x01ba },
+ { 0x0013, 0x01bb },
+ { 0x0013, 0x01bc },
+ { 0x0013, 0x01bd },
+ { 0x0013, 0x01be },
+ { 0x0013, 0x01bf },
+ { 0x0013, 0x01c0 },
+ { 0x0013, 0x01c1 },
+ { 0x0013, 0x01c2 },
+ { 0x0013, 0x01c3 },
+ { 0x0013, 0x01c4 },
+ { 0x0013, 0x01c5 },
+ { 0x0013, 0x01c6 },
+ { 0x0013, 0x01c7 },
+ { 0x0013, 0x01c8 },
+ { 0x0013, 0x01c9 },
+ { 0x0013, 0x01ca },
+ { 0x0013, 0x01cb },
+ { 0x0013, 0x01cc },
+ { 0x0013, 0x01cd },
+ { 0x0013, 0x01ce },
+ { 0x0013, 0x01cf },
+ { 0x0013, 0x01d0 },
+ { 0x0013, 0x01d1 },
+ { 0x0013, 0x01d2 },
+ { 0x0013, 0x01d3 },
+ { 0x0013, 0x01d4 },
+ { 0x0013, 0x01d5 },
+ { 0x0013, 0x01d6 },
+ { 0x0013, 0x01d7 },
+ { 0x0013, 0x01d8 },
+ { 0x0013, 0x01d9 },
+ { 0x0013, 0x01da },
+ { 0x0013, 0x01db },
+ { 0x0013, 0x01dc },
+ { 0x0013, 0x01dd },
+ { 0x0013, 0x01de },
+ { 0x0013, 0x01df },
+ { 0x0013, 0x01e0 },
+ { 0x0013, 0x01e1 },
+ { 0x0013, 0x01e2 },
+ { 0x0013, 0x01e3 },
+ { 0x0013, 0x01e4 },
+ { 0x0013, 0x01e5 },
+ { 0x0013, 0x01e6 },
+ { 0x0013, 0x01e7 },
+ { 0x0013, 0x01e8 },
+ { 0x0013, 0x01e9 },
+ { 0x0013, 0x01ea },
+ { 0x0013, 0x01eb },
+ { 0x0013, 0x01ec },
+ { 0x0013, 0x01ed },
+ { 0x0013, 0x01ee },
+ { 0x0013, 0x01ef },
+ { 0x0013, 0x01f0 },
+ { 0x0013, 0x01f1 },
+ { 0x0013, 0x01f2 },
+ { 0x0013, 0x01f3 },
+ { 0x0013, 0x01f4 },
+ { 0x0013, 0x01f5 },
+ { 0x0013, 0x01f6 },
+ { 0x0013, 0x01f7 },
+ { 0x0013, 0x01f8 },
+ { 0x0013, 0x01f9 },
+ { 0x0013, 0x01fa },
+ { 0x0013, 0x01fb },
+ { 0x0013, 0x01fc },
+ { 0x0013, 0x01fd },
+ { 0x0013, 0x01fe },
+ { 0x0013, 0x01ff },
+ { 0x0013, 0x0200 },
+ { 0x0013, 0x0201 },
+ { 0x0013, 0x0202 },
+ { 0x0013, 0x0203 },
+ { 0x0013, 0x0204 },
+ { 0x0013, 0x0205 },
+ { 0x0013, 0x0206 },
+ { 0x0013, 0x0207 },
+ { 0x0013, 0x0208 },
+ { 0x0013, 0x0209 },
+ { 0x0013, 0x020a },
+ { 0x0013, 0x020b },
+ { 0x0013, 0x020c },
+ { 0x0013, 0x020d },
+ { 0x0013, 0x020e },
+ { 0x0013, 0x020f },
+ { 0x0013, 0x0210 },
+ { 0x0013, 0x0211 },
+ { 0x0013, 0x0212 },
+ { 0x0013, 0x0213 },
+ { 0x0013, 0x0214 },
+ { 0x0013, 0x0215 },
+ { 0x0013, 0x0216 },
+ { 0x0013, 0x0217 },
+ { 0x0013, 0x0218 },
+ { 0x0013, 0x0219 },
+ { 0x0013, 0x021a },
+ { 0x0013, 0x021b },
+ { 0x0013, 0x021c },
+ { 0x0013, 0x021d },
+ { 0x0013, 0x021e },
+ { 0x0013, 0x021f },
+ { 0x0013, 0x0220 },
+ { 0x0013, 0x0221 },
+ { 0x0013, 0x0222 },
+ { 0x0013, 0x0223 },
+ { 0x0013, 0x0224 },
+ { 0x0013, 0x0225 },
+ { 0x0013, 0x0226 },
+ { 0x0013, 0x0227 },
+ { 0x0013, 0x0228 },
+ { 0x0013, 0x0229 },
+ { 0x0013, 0x022a },
+ { 0x0013, 0x022b },
+ { 0x0013, 0x022c },
+ { 0x0013, 0x022d },
+ { 0x0013, 0x022e },
+ { 0x0013, 0x022f },
+ { 0x0013, 0x0230 },
+ { 0x0013, 0x0231 },
+ { 0x0013, 0x0232 },
+ { 0x0013, 0x0233 },
+ { 0x0013, 0x0234 },
+ { 0x0013, 0x0235 },
+ { 0x0013, 0x0236 },
+ { 0x0013, 0x0237 },
+ { 0x0013, 0x0238 },
+ { 0x0013, 0x0239 },
+ { 0x0013, 0x023a },
+ { 0x0013, 0x023b },
+ { 0x0013, 0x023c },
+ { 0x0013, 0x023d },
+ { 0x0013, 0x023e },
+ { 0x0013, 0x023f },
+ { 0x0013, 0x0240 },
+ { 0x0013, 0x0241 },
+ { 0x0013, 0x0242 },
+ { 0x0013, 0x0243 },
+ { 0x0013, 0x0244 },
+ { 0x0013, 0x0245 },
+ { 0x0013, 0x0246 },
+ { 0x0013, 0x0247 },
+ { 0x0013, 0x0248 },
+ { 0x0013, 0x0249 },
+ { 0x0013, 0x024a },
+ { 0x0013, 0x024b },
+ { 0x0013, 0x024c },
+ { 0x0013, 0x024d },
+ { 0x0013, 0x024e },
+ { 0x0013, 0x024f },
+ { 0x0013, 0x0250 },
+ { 0x0013, 0x0251 },
+ { 0x0013, 0x0252 },
+ { 0x0013, 0x0253 },
+ { 0x0013, 0x0254 },
+ { 0x0013, 0x0255 },
+ { 0x0013, 0x0256 },
+ { 0x0013, 0x0257 },
+ { 0x0013, 0x0258 },
+ { 0x0013, 0x0259 },
+ { 0x0013, 0x025a },
+ { 0x0013, 0x025b },
+ { 0x0013, 0x025c },
+ { 0x0013, 0x025d },
+ { 0x0013, 0x025e },
+ { 0x0013, 0x025f },
+ { 0x0013, 0x0260 },
+ { 0x0013, 0x0261 },
+ { 0x0013, 0x0262 },
+ { 0x0013, 0x0263 },
+ { 0x0013, 0x0264 },
+ { 0x0013, 0x0265 },
+ { 0x0013, 0x0266 },
+ { 0x0013, 0x0267 },
+ { 0x0013, 0x0268 },
+ { 0x0013, 0x0269 },
+ { 0x0013, 0x026a },
+ { 0x0013, 0x026b },
+ { 0x0012, 0x013f },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc49[729][2] =
+ {
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0003 },
+ { 0x0005, 0x0007 },
+ { 0x0007, 0x000a },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0009, 0x0009 },
+ { 0x000b, 0x000d },
+ { 0x000d, 0x0014 },
+ { 0x000d, 0x0015 },
+ { 0x0010, 0x0052 },
+ { 0x0011, 0x0098 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0005, 0x0008 },
+ { 0x0006, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x000a, 0x000a },
+ { 0x000b, 0x000e },
+ { 0x000d, 0x0016 },
+ { 0x000f, 0x0031 },
+ { 0x0010, 0x0053 },
+ { 0x0012, 0x012a },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0006, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0009, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x0017 },
+ { 0x000f, 0x0032 },
+ { 0x0010, 0x0054 },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+ { 0x0013, 0x0028 },
+ { 0x0013, 0x0029 },
+ { 0x0013, 0x002a },
+ { 0x0013, 0x002b },
+ { 0x0007, 0x000d },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0008, 0x000e },
+ { 0x0009, 0x000b },
+ { 0x000b, 0x000f },
+ { 0x000c, 0x0010 },
+ { 0x000e, 0x001d },
+ { 0x000f, 0x0033 },
+ { 0x0011, 0x0099 },
+ { 0x0013, 0x002c },
+ { 0x0013, 0x002d },
+ { 0x0013, 0x002e },
+ { 0x0013, 0x002f },
+ { 0x0013, 0x0030 },
+ { 0x0013, 0x0031 },
+ { 0x0013, 0x0032 },
+ { 0x0013, 0x0033 },
+ { 0x0013, 0x0034 },
+ { 0x0013, 0x0035 },
+ { 0x0013, 0x0036 },
+ { 0x0013, 0x0037 },
+ { 0x0013, 0x0038 },
+ { 0x0013, 0x0039 },
+ { 0x0013, 0x003a },
+ { 0x0008, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0007, 0x0012 },
+ { 0x0008, 0x0010 },
+ { 0x0009, 0x000c },
+ { 0x000a, 0x000c },
+ { 0x000c, 0x0011 },
+ { 0x000d, 0x0018 },
+ { 0x000e, 0x001e },
+ { 0x0011, 0x009a },
+ { 0x0011, 0x009b },
+ { 0x0013, 0x003b },
+ { 0x0013, 0x003c },
+ { 0x0013, 0x003d },
+ { 0x0013, 0x003e },
+ { 0x0013, 0x003f },
+ { 0x0013, 0x0040 },
+ { 0x0013, 0x0041 },
+ { 0x0013, 0x0042 },
+ { 0x0013, 0x0043 },
+ { 0x0013, 0x0044 },
+ { 0x0013, 0x0045 },
+ { 0x0013, 0x0046 },
+ { 0x0013, 0x0047 },
+ { 0x0013, 0x0048 },
+ { 0x0013, 0x0049 },
+ { 0x0008, 0x0011 },
+ { 0x0007, 0x0013 },
+ { 0x0008, 0x0012 },
+ { 0x0008, 0x0013 },
+ { 0x0009, 0x000d },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x0010 },
+ { 0x000c, 0x0012 },
+ { 0x000e, 0x001f },
+ { 0x000e, 0x0020 },
+ { 0x0010, 0x0055 },
+ { 0x0011, 0x009c },
+ { 0x0013, 0x004a },
+ { 0x0013, 0x004b },
+ { 0x0013, 0x004c },
+ { 0x0013, 0x004d },
+ { 0x0013, 0x004e },
+ { 0x0013, 0x004f },
+ { 0x0013, 0x0050 },
+ { 0x0013, 0x0051 },
+ { 0x0013, 0x0052 },
+ { 0x0013, 0x0053 },
+ { 0x0013, 0x0054 },
+ { 0x0013, 0x0055 },
+ { 0x0013, 0x0056 },
+ { 0x0013, 0x0057 },
+ { 0x0013, 0x0058 },
+ { 0x0009, 0x000e },
+ { 0x0009, 0x000f },
+ { 0x0009, 0x0010 },
+ { 0x0009, 0x0011 },
+ { 0x000a, 0x000e },
+ { 0x000b, 0x0011 },
+ { 0x000c, 0x0013 },
+ { 0x000d, 0x0019 },
+ { 0x000e, 0x0021 },
+ { 0x0010, 0x0056 },
+ { 0x0010, 0x0057 },
+ { 0x0013, 0x0059 },
+ { 0x0013, 0x005a },
+ { 0x0013, 0x005b },
+ { 0x0013, 0x005c },
+ { 0x0013, 0x005d },
+ { 0x0013, 0x005e },
+ { 0x0013, 0x005f },
+ { 0x0013, 0x0060 },
+ { 0x0013, 0x0061 },
+ { 0x0013, 0x0062 },
+ { 0x0013, 0x0063 },
+ { 0x0013, 0x0064 },
+ { 0x0013, 0x0065 },
+ { 0x0013, 0x0066 },
+ { 0x0013, 0x0067 },
+ { 0x0013, 0x0068 },
+ { 0x000b, 0x0012 },
+ { 0x000a, 0x000f },
+ { 0x000a, 0x0010 },
+ { 0x000a, 0x0011 },
+ { 0x000c, 0x0014 },
+ { 0x000c, 0x0015 },
+ { 0x000d, 0x001a },
+ { 0x000e, 0x0022 },
+ { 0x0010, 0x0058 },
+ { 0x0010, 0x0059 },
+ { 0x0013, 0x0069 },
+ { 0x0013, 0x006a },
+ { 0x0013, 0x006b },
+ { 0x0013, 0x006c },
+ { 0x0013, 0x006d },
+ { 0x0013, 0x006e },
+ { 0x0013, 0x006f },
+ { 0x0013, 0x0070 },
+ { 0x0013, 0x0071 },
+ { 0x0013, 0x0072 },
+ { 0x0013, 0x0073 },
+ { 0x0013, 0x0074 },
+ { 0x0013, 0x0075 },
+ { 0x0013, 0x0076 },
+ { 0x0013, 0x0077 },
+ { 0x0013, 0x0078 },
+ { 0x0013, 0x0079 },
+ { 0x000c, 0x0016 },
+ { 0x000b, 0x0013 },
+ { 0x000c, 0x0017 },
+ { 0x000c, 0x0018 },
+ { 0x000c, 0x0019 },
+ { 0x000e, 0x0023 },
+ { 0x000e, 0x0024 },
+ { 0x000f, 0x0034 },
+ { 0x0010, 0x005a },
+ { 0x0011, 0x009d },
+ { 0x0013, 0x007a },
+ { 0x0013, 0x007b },
+ { 0x0013, 0x007c },
+ { 0x0013, 0x007d },
+ { 0x0013, 0x007e },
+ { 0x0013, 0x007f },
+ { 0x0013, 0x0080 },
+ { 0x0013, 0x0081 },
+ { 0x0013, 0x0082 },
+ { 0x0013, 0x0083 },
+ { 0x0013, 0x0084 },
+ { 0x0013, 0x0085 },
+ { 0x0013, 0x0086 },
+ { 0x0013, 0x0087 },
+ { 0x0013, 0x0088 },
+ { 0x0013, 0x0089 },
+ { 0x0013, 0x008a },
+ { 0x000e, 0x0025 },
+ { 0x000d, 0x001b },
+ { 0x000d, 0x001c },
+ { 0x000d, 0x001d },
+ { 0x000e, 0x0026 },
+ { 0x000f, 0x0035 },
+ { 0x0010, 0x005b },
+ { 0x0011, 0x009e },
+ { 0x0011, 0x009f },
+ { 0x0012, 0x012b },
+ { 0x0013, 0x008b },
+ { 0x0013, 0x008c },
+ { 0x0013, 0x008d },
+ { 0x0013, 0x008e },
+ { 0x0013, 0x008f },
+ { 0x0013, 0x0090 },
+ { 0x0013, 0x0091 },
+ { 0x0013, 0x0092 },
+ { 0x0013, 0x0093 },
+ { 0x0013, 0x0094 },
+ { 0x0013, 0x0095 },
+ { 0x0013, 0x0096 },
+ { 0x0013, 0x0097 },
+ { 0x0013, 0x0098 },
+ { 0x0013, 0x0099 },
+ { 0x0013, 0x009a },
+ { 0x0013, 0x009b },
+ { 0x0010, 0x005c },
+ { 0x000f, 0x0036 },
+ { 0x000e, 0x0027 },
+ { 0x000f, 0x0037 },
+ { 0x000f, 0x0038 },
+ { 0x0010, 0x005d },
+ { 0x0011, 0x00a0 },
+ { 0x0013, 0x009c },
+ { 0x0012, 0x012c },
+ { 0x0013, 0x009d },
+ { 0x0013, 0x009e },
+ { 0x0013, 0x009f },
+ { 0x0013, 0x00a0 },
+ { 0x0013, 0x00a1 },
+ { 0x0013, 0x00a2 },
+ { 0x0013, 0x00a3 },
+ { 0x0013, 0x00a4 },
+ { 0x0013, 0x00a5 },
+ { 0x0013, 0x00a6 },
+ { 0x0013, 0x00a7 },
+ { 0x0013, 0x00a8 },
+ { 0x0013, 0x00a9 },
+ { 0x0013, 0x00aa },
+ { 0x0013, 0x00ab },
+ { 0x0013, 0x00ac },
+ { 0x0013, 0x00ad },
+ { 0x0013, 0x00ae },
+ { 0x0010, 0x005e },
+ { 0x000f, 0x0039 },
+ { 0x0010, 0x005f },
+ { 0x0010, 0x0060 },
+ { 0x0011, 0x00a1 },
+ { 0x0010, 0x0061 },
+ { 0x0013, 0x00af },
+ { 0x0013, 0x00b0 },
+ { 0x0012, 0x012d },
+ { 0x0013, 0x00b1 },
+ { 0x0013, 0x00b2 },
+ { 0x0013, 0x00b3 },
+ { 0x0013, 0x00b4 },
+ { 0x0013, 0x00b5 },
+ { 0x0013, 0x00b6 },
+ { 0x0013, 0x00b7 },
+ { 0x0013, 0x00b8 },
+ { 0x0013, 0x00b9 },
+ { 0x0013, 0x00ba },
+ { 0x0013, 0x00bb },
+ { 0x0013, 0x00bc },
+ { 0x0013, 0x00bd },
+ { 0x0013, 0x00be },
+ { 0x0013, 0x00bf },
+ { 0x0013, 0x00c0 },
+ { 0x0013, 0x00c1 },
+ { 0x0013, 0x00c2 },
+ { 0x0012, 0x012e },
+ { 0x0011, 0x00a2 },
+ { 0x0011, 0x00a3 },
+ { 0x0013, 0x00c3 },
+ { 0x0013, 0x00c4 },
+ { 0x0013, 0x00c5 },
+ { 0x0013, 0x00c6 },
+ { 0x0013, 0x00c7 },
+ { 0x0013, 0x00c8 },
+ { 0x0013, 0x00c9 },
+ { 0x0013, 0x00ca },
+ { 0x0013, 0x00cb },
+ { 0x0013, 0x00cc },
+ { 0x0013, 0x00cd },
+ { 0x0013, 0x00ce },
+ { 0x0013, 0x00cf },
+ { 0x0013, 0x00d0 },
+ { 0x0013, 0x00d1 },
+ { 0x0013, 0x00d2 },
+ { 0x0013, 0x00d3 },
+ { 0x0013, 0x00d4 },
+ { 0x0013, 0x00d5 },
+ { 0x0013, 0x00d6 },
+ { 0x0013, 0x00d7 },
+ { 0x0013, 0x00d8 },
+ { 0x0013, 0x00d9 },
+ { 0x0013, 0x00da },
+ { 0x0013, 0x00db },
+ { 0x0013, 0x00dc },
+ { 0x0013, 0x00dd },
+ { 0x0013, 0x00de },
+ { 0x0013, 0x00df },
+ { 0x0012, 0x012f },
+ { 0x0013, 0x00e0 },
+ { 0x0013, 0x00e1 },
+ { 0x0013, 0x00e2 },
+ { 0x0013, 0x00e3 },
+ { 0x0013, 0x00e4 },
+ { 0x0013, 0x00e5 },
+ { 0x0013, 0x00e6 },
+ { 0x0013, 0x00e7 },
+ { 0x0013, 0x00e8 },
+ { 0x0013, 0x00e9 },
+ { 0x0013, 0x00ea },
+ { 0x0013, 0x00eb },
+ { 0x0013, 0x00ec },
+ { 0x0013, 0x00ed },
+ { 0x0013, 0x00ee },
+ { 0x0013, 0x00ef },
+ { 0x0013, 0x00f0 },
+ { 0x0013, 0x00f1 },
+ { 0x0013, 0x00f2 },
+ { 0x0013, 0x00f3 },
+ { 0x0013, 0x00f4 },
+ { 0x0013, 0x00f5 },
+ { 0x0013, 0x00f6 },
+ { 0x0013, 0x00f7 },
+ { 0x0013, 0x00f8 },
+ { 0x0013, 0x00f9 },
+ { 0x0013, 0x00fa },
+ { 0x0013, 0x00fb },
+ { 0x0013, 0x00fc },
+ { 0x0013, 0x00fd },
+ { 0x0013, 0x00fe },
+ { 0x0013, 0x00ff },
+ { 0x0013, 0x0100 },
+ { 0x0013, 0x0101 },
+ { 0x0013, 0x0102 },
+ { 0x0013, 0x0103 },
+ { 0x0013, 0x0104 },
+ { 0x0013, 0x0105 },
+ { 0x0013, 0x0106 },
+ { 0x0013, 0x0107 },
+ { 0x0013, 0x0108 },
+ { 0x0013, 0x0109 },
+ { 0x0013, 0x010a },
+ { 0x0013, 0x010b },
+ { 0x0013, 0x010c },
+ { 0x0013, 0x010d },
+ { 0x0013, 0x010e },
+ { 0x0013, 0x010f },
+ { 0x0013, 0x0110 },
+ { 0x0013, 0x0111 },
+ { 0x0013, 0x0112 },
+ { 0x0013, 0x0113 },
+ { 0x0013, 0x0114 },
+ { 0x0013, 0x0115 },
+ { 0x0013, 0x0116 },
+ { 0x0013, 0x0117 },
+ { 0x0013, 0x0118 },
+ { 0x0013, 0x0119 },
+ { 0x0013, 0x011a },
+ { 0x0013, 0x011b },
+ { 0x0013, 0x011c },
+ { 0x0013, 0x011d },
+ { 0x0013, 0x011e },
+ { 0x0013, 0x011f },
+ { 0x0013, 0x0120 },
+ { 0x0013, 0x0121 },
+ { 0x0013, 0x0122 },
+ { 0x0013, 0x0123 },
+ { 0x0013, 0x0124 },
+ { 0x0013, 0x0125 },
+ { 0x0013, 0x0126 },
+ { 0x0013, 0x0127 },
+ { 0x0013, 0x0128 },
+ { 0x0013, 0x0129 },
+ { 0x0013, 0x012a },
+ { 0x0013, 0x012b },
+ { 0x0013, 0x012c },
+ { 0x0013, 0x012d },
+ { 0x0013, 0x012e },
+ { 0x0013, 0x012f },
+ { 0x0013, 0x0130 },
+ { 0x0013, 0x0131 },
+ { 0x0013, 0x0132 },
+ { 0x0013, 0x0133 },
+ { 0x0013, 0x0134 },
+ { 0x0013, 0x0135 },
+ { 0x0013, 0x0136 },
+ { 0x0013, 0x0137 },
+ { 0x0013, 0x0138 },
+ { 0x0013, 0x0139 },
+ { 0x0013, 0x013a },
+ { 0x0013, 0x013b },
+ { 0x0013, 0x013c },
+ { 0x0013, 0x013d },
+ { 0x0013, 0x013e },
+ { 0x0013, 0x013f },
+ { 0x0013, 0x0140 },
+ { 0x0013, 0x0141 },
+ { 0x0013, 0x0142 },
+ { 0x0013, 0x0143 },
+ { 0x0013, 0x0144 },
+ { 0x0013, 0x0145 },
+ { 0x0013, 0x0146 },
+ { 0x0013, 0x0147 },
+ { 0x0013, 0x0148 },
+ { 0x0013, 0x0149 },
+ { 0x0013, 0x014a },
+ { 0x0013, 0x014b },
+ { 0x0013, 0x014c },
+ { 0x0013, 0x014d },
+ { 0x0013, 0x014e },
+ { 0x0013, 0x014f },
+ { 0x0013, 0x0150 },
+ { 0x0013, 0x0151 },
+ { 0x0013, 0x0152 },
+ { 0x0013, 0x0153 },
+ { 0x0013, 0x0154 },
+ { 0x0013, 0x0155 },
+ { 0x0013, 0x0156 },
+ { 0x0013, 0x0157 },
+ { 0x0013, 0x0158 },
+ { 0x0013, 0x0159 },
+ { 0x0013, 0x015a },
+ { 0x0013, 0x015b },
+ { 0x0013, 0x015c },
+ { 0x0013, 0x015d },
+ { 0x0013, 0x015e },
+ { 0x0013, 0x015f },
+ { 0x0013, 0x0160 },
+ { 0x0013, 0x0161 },
+ { 0x0013, 0x0162 },
+ { 0x0013, 0x0163 },
+ { 0x0013, 0x0164 },
+ { 0x0013, 0x0165 },
+ { 0x0013, 0x0166 },
+ { 0x0013, 0x0167 },
+ { 0x0013, 0x0168 },
+ { 0x0013, 0x0169 },
+ { 0x0013, 0x016a },
+ { 0x0013, 0x016b },
+ { 0x0013, 0x016c },
+ { 0x0013, 0x016d },
+ { 0x0013, 0x016e },
+ { 0x0013, 0x016f },
+ { 0x0013, 0x0170 },
+ { 0x0013, 0x0171 },
+ { 0x0013, 0x0172 },
+ { 0x0013, 0x0173 },
+ { 0x0013, 0x0174 },
+ { 0x0013, 0x0175 },
+ { 0x0013, 0x0176 },
+ { 0x0013, 0x0177 },
+ { 0x0013, 0x0178 },
+ { 0x0013, 0x0179 },
+ { 0x0013, 0x017a },
+ { 0x0013, 0x017b },
+ { 0x0013, 0x017c },
+ { 0x0013, 0x017d },
+ { 0x0013, 0x017e },
+ { 0x0013, 0x017f },
+ { 0x0013, 0x0180 },
+ { 0x0013, 0x0181 },
+ { 0x0013, 0x0182 },
+ { 0x0013, 0x0183 },
+ { 0x0013, 0x0184 },
+ { 0x0013, 0x0185 },
+ { 0x0013, 0x0186 },
+ { 0x0013, 0x0187 },
+ { 0x0013, 0x0188 },
+ { 0x0013, 0x0189 },
+ { 0x0013, 0x018a },
+ { 0x0013, 0x018b },
+ { 0x0013, 0x018c },
+ { 0x0013, 0x018d },
+ { 0x0013, 0x018e },
+ { 0x0013, 0x018f },
+ { 0x0013, 0x0190 },
+ { 0x0013, 0x0191 },
+ { 0x0013, 0x0192 },
+ { 0x0013, 0x0193 },
+ { 0x0013, 0x0194 },
+ { 0x0013, 0x0195 },
+ { 0x0013, 0x0196 },
+ { 0x0013, 0x0197 },
+ { 0x0013, 0x0198 },
+ { 0x0013, 0x0199 },
+ { 0x0013, 0x019a },
+ { 0x0013, 0x019b },
+ { 0x0013, 0x019c },
+ { 0x0013, 0x019d },
+ { 0x0013, 0x019e },
+ { 0x0013, 0x019f },
+ { 0x0013, 0x01a0 },
+ { 0x0013, 0x01a1 },
+ { 0x0013, 0x01a2 },
+ { 0x0013, 0x01a3 },
+ { 0x0013, 0x01a4 },
+ { 0x0013, 0x01a5 },
+ { 0x0013, 0x01a6 },
+ { 0x0013, 0x01a7 },
+ { 0x0013, 0x01a8 },
+ { 0x0013, 0x01a9 },
+ { 0x0013, 0x01aa },
+ { 0x0013, 0x01ab },
+ { 0x0013, 0x01ac },
+ { 0x0013, 0x01ad },
+ { 0x0013, 0x01ae },
+ { 0x0013, 0x01af },
+ { 0x0013, 0x01b0 },
+ { 0x0013, 0x01b1 },
+ { 0x0013, 0x01b2 },
+ { 0x0013, 0x01b3 },
+ { 0x0013, 0x01b4 },
+ { 0x0013, 0x01b5 },
+ { 0x0013, 0x01b6 },
+ { 0x0013, 0x01b7 },
+ { 0x0013, 0x01b8 },
+ { 0x0013, 0x01b9 },
+ { 0x0013, 0x01ba },
+ { 0x0013, 0x01bb },
+ { 0x0013, 0x01bc },
+ { 0x0013, 0x01bd },
+ { 0x0013, 0x01be },
+ { 0x0013, 0x01bf },
+ { 0x0013, 0x01c0 },
+ { 0x0013, 0x01c1 },
+ { 0x0013, 0x01c2 },
+ { 0x0013, 0x01c3 },
+ { 0x0013, 0x01c4 },
+ { 0x0013, 0x01c5 },
+ { 0x0013, 0x01c6 },
+ { 0x0013, 0x01c7 },
+ { 0x0013, 0x01c8 },
+ { 0x0013, 0x01c9 },
+ { 0x0013, 0x01ca },
+ { 0x0013, 0x01cb },
+ { 0x0013, 0x01cc },
+ { 0x0013, 0x01cd },
+ { 0x0013, 0x01ce },
+ { 0x0013, 0x01cf },
+ { 0x0013, 0x01d0 },
+ { 0x0013, 0x01d1 },
+ { 0x0013, 0x01d2 },
+ { 0x0013, 0x01d3 },
+ { 0x0013, 0x01d4 },
+ { 0x0013, 0x01d5 },
+ { 0x0013, 0x01d6 },
+ { 0x0013, 0x01d7 },
+ { 0x0013, 0x01d8 },
+ { 0x0013, 0x01d9 },
+ { 0x0013, 0x01da },
+ { 0x0013, 0x01db },
+ { 0x0013, 0x01dc },
+ { 0x0013, 0x01dd },
+ { 0x0013, 0x01de },
+ { 0x0013, 0x01df },
+ { 0x0013, 0x01e0 },
+ { 0x0013, 0x01e1 },
+ { 0x0013, 0x01e2 },
+ { 0x0013, 0x01e3 },
+ { 0x0013, 0x01e4 },
+ { 0x0013, 0x01e5 },
+ { 0x0013, 0x01e6 },
+ { 0x0013, 0x01e7 },
+ { 0x0013, 0x01e8 },
+ { 0x0013, 0x01e9 },
+ { 0x0013, 0x01ea },
+ { 0x0013, 0x01eb },
+ { 0x0013, 0x01ec },
+ { 0x0013, 0x01ed },
+ { 0x0013, 0x01ee },
+ { 0x0013, 0x01ef },
+ { 0x0013, 0x01f0 },
+ { 0x0013, 0x01f1 },
+ { 0x0013, 0x01f2 },
+ { 0x0013, 0x01f3 },
+ { 0x0013, 0x01f4 },
+ { 0x0013, 0x01f5 },
+ { 0x0013, 0x01f6 },
+ { 0x0013, 0x01f7 },
+ { 0x0013, 0x01f8 },
+ { 0x0013, 0x01f9 },
+ { 0x0013, 0x01fa },
+ { 0x0013, 0x01fb },
+ { 0x0013, 0x01fc },
+ { 0x0013, 0x01fd },
+ { 0x0013, 0x01fe },
+ { 0x0013, 0x01ff },
+ { 0x0013, 0x0200 },
+ { 0x0013, 0x0201 },
+ { 0x0013, 0x0202 },
+ { 0x0013, 0x0203 },
+ { 0x0013, 0x0204 },
+ { 0x0013, 0x0205 },
+ { 0x0013, 0x0206 },
+ { 0x0013, 0x0207 },
+ { 0x0013, 0x0208 },
+ { 0x0013, 0x0209 },
+ { 0x0013, 0x020a },
+ { 0x0013, 0x020b },
+ { 0x0013, 0x020c },
+ { 0x0013, 0x020d },
+ { 0x0013, 0x020e },
+ { 0x0013, 0x020f },
+ { 0x0013, 0x0210 },
+ { 0x0013, 0x0211 },
+ { 0x0013, 0x0212 },
+ { 0x0013, 0x0213 },
+ { 0x0013, 0x0214 },
+ { 0x0013, 0x0215 },
+ { 0x0013, 0x0216 },
+ { 0x0013, 0x0217 },
+ { 0x0013, 0x0218 },
+ { 0x0013, 0x0219 },
+ { 0x0013, 0x021a },
+ { 0x0013, 0x021b },
+ { 0x0013, 0x021c },
+ { 0x0013, 0x021d },
+ { 0x0013, 0x021e },
+ { 0x0013, 0x021f },
+ { 0x0013, 0x0220 },
+ { 0x0013, 0x0221 },
+ { 0x0013, 0x0222 },
+ { 0x0013, 0x0223 },
+ { 0x0013, 0x0224 },
+ { 0x0013, 0x0225 },
+ { 0x0013, 0x0226 },
+ { 0x0013, 0x0227 },
+ { 0x0013, 0x0228 },
+ { 0x0013, 0x0229 },
+ { 0x0013, 0x022a },
+ { 0x0013, 0x022b },
+ { 0x0013, 0x022c },
+ { 0x0013, 0x022d },
+ { 0x0013, 0x022e },
+ { 0x0013, 0x022f },
+ { 0x0013, 0x0230 },
+ { 0x0013, 0x0231 },
+ { 0x0013, 0x0232 },
+ { 0x0013, 0x0233 },
+ { 0x0013, 0x0234 },
+ { 0x0013, 0x0235 },
+ { 0x0013, 0x0236 },
+ { 0x0013, 0x0237 },
+ { 0x0013, 0x0238 },
+ { 0x0013, 0x0239 },
+ { 0x0013, 0x023a },
+ { 0x0013, 0x023b },
+ { 0x0013, 0x023c },
+ { 0x0013, 0x023d },
+ { 0x0013, 0x023e },
+ { 0x0013, 0x023f },
+ { 0x0013, 0x0240 },
+ { 0x0013, 0x0241 },
+ { 0x0013, 0x0242 },
+ { 0x0013, 0x0243 },
+ { 0x0013, 0x0244 },
+ { 0x0013, 0x0245 },
+ { 0x0013, 0x0246 },
+ { 0x0013, 0x0247 },
+ { 0x0013, 0x0248 },
+ { 0x0013, 0x0249 },
+ { 0x0013, 0x024a },
+ { 0x0013, 0x024b },
+ { 0x0013, 0x024c },
+ { 0x0013, 0x024d },
+ { 0x0013, 0x024e },
+ { 0x0013, 0x024f },
+ { 0x0013, 0x0250 },
+ { 0x0013, 0x0251 },
+ { 0x0013, 0x0252 },
+ { 0x0013, 0x0253 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc50[28][2] =
+ {
+ { 0x0002, 0x0001 },
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0001 },
+ { 0x0004, 0x0001 },
+ { 0x0005, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000f, 0x0001 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0005 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc51[29][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0001 },
+ { 0x0004, 0x0002 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0006, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000d, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc52[32][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0002 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0001 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0006, 0x0001 },
+ { 0x0007, 0x0001 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000a, 0x0001 },
+ { 0x000b, 0x0001 },
+ { 0x000c, 0x0001 },
+ { 0x000e, 0x0001 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0001 },
+ { 0x0011, 0x0002 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0003 },
+ { 0x0014, 0x0000 },
+ { 0x0013, 0x0003 },
+ { 0x0014, 0x0001 },
+ { 0x0014, 0x0002 },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ };
+
+const uint16_t c_aauiLCLDHuffEnc53[37][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0002 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0002 },
+ { 0x0005, 0x0003 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0007, 0x0001 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x0009, 0x0001 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0002 },
+ { 0x000f, 0x0003 },
+ { 0x0011, 0x0004 },
+ { 0x0010, 0x0003 },
+ { 0x0011, 0x0005 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc54[39][2] =
+ {
+ { 0x0002, 0x0002 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0002 },
+ { 0x0003, 0x0003 },
+ { 0x0004, 0x0003 },
+ { 0x0005, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0006, 0x0002 },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0008, 0x0001 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0002 },
+ { 0x000f, 0x0003 },
+ { 0x0011, 0x0002 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc55[46][2] =
+ {
+ { 0x0003, 0x0003 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0004, 0x0003 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0005, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0002 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0002 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0002 },
+ { 0x000c, 0x0003 },
+ { 0x000d, 0x0002 },
+ { 0x000d, 0x0003 },
+ { 0x000e, 0x0002 },
+ { 0x000e, 0x0003 },
+ { 0x000f, 0x0003 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc56[55][2] =
+ {
+ { 0x0003, 0x0003 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0004 },
+ { 0x0003, 0x0005 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0005, 0x0003 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0003 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0008, 0x0002 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0009, 0x0002 },
+ { 0x0009, 0x0003 },
+ { 0x000a, 0x0002 },
+ { 0x000a, 0x0003 },
+ { 0x000b, 0x0003 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000d, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x0010, 0x0002 },
+ { 0x0010, 0x0003 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0010, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0013, 0x0000 },
+ { 0x0011, 0x0003 },
+ { 0x0012, 0x0005 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc57[65][2] =
+ {
+ { 0x0003, 0x0004 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0005 },
+ { 0x0004, 0x0004 },
+ { 0x0004, 0x0005 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0005, 0x0004 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0007, 0x0003 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0003 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000c, 0x0003 },
+ { 0x000c, 0x0004 },
+ { 0x000d, 0x0003 },
+ { 0x000c, 0x0005 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000f, 0x0003 },
+ { 0x0010, 0x0003 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x0010, 0x0004 },
+ { 0x0010, 0x0005 },
+ { 0x0013, 0x0000 },
+ { 0x0011, 0x0005 },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0012, 0x0007 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc58[77][2] =
+ {
+ { 0x0004, 0x0005 },
+ { 0x0003, 0x0005 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x0005 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0006, 0x0004 },
+ { 0x0006, 0x0005 },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0007, 0x0004 },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0009, 0x0003 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0003 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000e, 0x0006 },
+ { 0x000e, 0x0007 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x000f, 0x0006 },
+ { 0x0010, 0x0004 },
+ { 0x000f, 0x0007 },
+ { 0x0010, 0x0005 },
+ { 0x0010, 0x0006 },
+ { 0x0010, 0x0007 },
+ { 0x0013, 0x0000 },
+ { 0x0013, 0x0001 },
+ { 0x0012, 0x0006 },
+ { 0x0011, 0x0007 },
+ { 0x0013, 0x0002 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0012, 0x0007 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc59[91][2] =
+ {
+ { 0x0003, 0x0005 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0006 },
+ { 0x0004, 0x0007 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x0006 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0006, 0x0006 },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0007, 0x0005 },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0008, 0x0003 },
+ { 0x0008, 0x0004 },
+ { 0x0008, 0x0005 },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000d, 0x0003 },
+ { 0x000d, 0x0004 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000e, 0x0003 },
+ { 0x000e, 0x0004 },
+ { 0x000e, 0x0005 },
+ { 0x000f, 0x0003 },
+ { 0x000f, 0x0004 },
+ { 0x000f, 0x0005 },
+ { 0x0011, 0x0008 },
+ { 0x0011, 0x0009 },
+ { 0x0013, 0x0000 },
+ { 0x0011, 0x000a },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0012, 0x000d },
+ { 0x0012, 0x000e },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0011, 0x000b },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0012, 0x000f },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc60[109][2] =
+ {
+ { 0x0004, 0x0007 },
+ { 0x0002, 0x0003 },
+ { 0x0003, 0x0005 },
+ { 0x0004, 0x0008 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x0007 },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0006, 0x0007 },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0007, 0x0006 },
+ { 0x0007, 0x0007 },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0009, 0x0004 },
+ { 0x0009, 0x0005 },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000b, 0x0004 },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0004 },
+ { 0x000c, 0x0005 },
+ { 0x000c, 0x0006 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000c, 0x0007 },
+ { 0x000e, 0x0005 },
+ { 0x000e, 0x0006 },
+ { 0x000e, 0x0007 },
+ { 0x000e, 0x0008 },
+ { 0x000f, 0x0005 },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x0006 },
+ { 0x0010, 0x0006 },
+ { 0x000f, 0x0007 },
+ { 0x000f, 0x0008 },
+ { 0x000f, 0x0009 },
+ { 0x0010, 0x0007 },
+ { 0x0010, 0x0008 },
+ { 0x0010, 0x0009 },
+ { 0x0011, 0x000a },
+ { 0x0013, 0x0000 },
+ { 0x0011, 0x000b },
+ { 0x0013, 0x0001 },
+ { 0x0013, 0x0002 },
+ { 0x0012, 0x0011 },
+ { 0x0012, 0x0012 },
+ { 0x0013, 0x0003 },
+ { 0x0013, 0x0004 },
+ { 0x0013, 0x0005 },
+ { 0x0013, 0x0006 },
+ { 0x0013, 0x0007 },
+ { 0x0013, 0x0008 },
+ { 0x0013, 0x0009 },
+ { 0x0013, 0x000a },
+ { 0x0013, 0x000b },
+ { 0x0013, 0x000c },
+ { 0x0013, 0x000d },
+ { 0x0013, 0x000e },
+ { 0x0013, 0x000f },
+ { 0x0013, 0x0010 },
+ { 0x0013, 0x0011 },
+ { 0x0013, 0x0012 },
+ { 0x0013, 0x0013 },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0012, 0x0013 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc61[129][2] =
+ {
+ { 0x0004, 0x0008 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x0009 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0005, 0x0008 },
+ { 0x0005, 0x0009 },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0006, 0x0008 },
+ { 0x0006, 0x0009 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0007, 0x0008 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0008, 0x0006 },
+ { 0x0008, 0x0007 },
+ { 0x0008, 0x0008 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0009, 0x0006 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000b, 0x0005 },
+ { 0x000b, 0x0006 },
+ { 0x000b, 0x0007 },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000c, 0x0006 },
+ { 0x000c, 0x0007 },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000d, 0x0005 },
+ { 0x000d, 0x0006 },
+ { 0x000d, 0x0007 },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000e, 0x0008 },
+ { 0x000d, 0x000b },
+ { 0x000e, 0x0009 },
+ { 0x000f, 0x0009 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x000f, 0x000c },
+ { 0x000f, 0x000d },
+ { 0x000f, 0x000e },
+ { 0x0010, 0x000c },
+ { 0x0011, 0x0015 },
+ { 0x0010, 0x000d },
+ { 0x000f, 0x000f },
+ { 0x0010, 0x000e },
+ { 0x0010, 0x000f },
+ { 0x0012, 0x0000 },
+ { 0x0011, 0x0016 },
+ { 0x0010, 0x0010 },
+ { 0x0010, 0x0011 },
+ { 0x0011, 0x0017 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+ { 0x0012, 0x000e },
+ { 0x0012, 0x000f },
+ { 0x0012, 0x0010 },
+ { 0x0012, 0x0011 },
+ { 0x0012, 0x0012 },
+ { 0x0012, 0x0013 },
+ { 0x0012, 0x0014 },
+ { 0x0012, 0x0015 },
+ { 0x0012, 0x0016 },
+ { 0x0012, 0x0017 },
+ { 0x0012, 0x0018 },
+ { 0x0012, 0x0019 },
+ { 0x0012, 0x001a },
+ { 0x0012, 0x001b },
+ { 0x0012, 0x001c },
+ { 0x0012, 0x001d },
+ { 0x0012, 0x001e },
+ { 0x0012, 0x001f },
+ { 0x0012, 0x0020 },
+ { 0x0012, 0x0021 },
+ { 0x0012, 0x0022 },
+ { 0x0012, 0x0023 },
+ { 0x0012, 0x0024 },
+ { 0x0012, 0x0025 },
+ { 0x0012, 0x0026 },
+ { 0x0012, 0x0027 },
+ { 0x0012, 0x0028 },
+ { 0x0012, 0x0029 },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc62[153][2] =
+ {
+ { 0x0004, 0x0009 },
+ { 0x0003, 0x0006 },
+ { 0x0003, 0x0007 },
+ { 0x0004, 0x000a },
+ { 0x0004, 0x000b },
+ { 0x0005, 0x000a },
+ { 0x0005, 0x000b },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0005, 0x0010 },
+ { 0x0005, 0x0011 },
+ { 0x0006, 0x000a },
+ { 0x0006, 0x000b },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0007, 0x0009 },
+ { 0x0007, 0x000a },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0007, 0x0012 },
+ { 0x0007, 0x0013 },
+ { 0x0008, 0x0009 },
+ { 0x0008, 0x000a },
+ { 0x0008, 0x000b },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0008, 0x0010 },
+ { 0x0008, 0x0011 },
+ { 0x0009, 0x0007 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x0009, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x0009, 0x000e },
+ { 0x0009, 0x000f },
+ { 0x0009, 0x0010 },
+ { 0x0009, 0x0011 },
+ { 0x000a, 0x0004 },
+ { 0x000a, 0x0005 },
+ { 0x000a, 0x0006 },
+ { 0x000a, 0x0007 },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000b, 0x0007 },
+ { 0x000c, 0x0007 },
+ { 0x000c, 0x0008 },
+ { 0x000c, 0x0009 },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000c, 0x000c },
+ { 0x000d, 0x0007 },
+ { 0x000c, 0x000d },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000e, 0x0008 },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+ { 0x000e, 0x0009 },
+ { 0x000e, 0x000a },
+ { 0x000e, 0x000b },
+ { 0x000e, 0x000c },
+ { 0x000f, 0x000c },
+ { 0x000e, 0x000d },
+ { 0x000f, 0x000d },
+ { 0x000f, 0x000e },
+ { 0x000f, 0x000f },
+ { 0x0010, 0x000f },
+ { 0x0010, 0x0010 },
+ { 0x0011, 0x0019 },
+ { 0x0010, 0x0011 },
+ { 0x0010, 0x0012 },
+ { 0x0010, 0x0013 },
+ { 0x0010, 0x0014 },
+ { 0x0010, 0x0015 },
+ { 0x0012, 0x0000 },
+ { 0x0010, 0x0016 },
+ { 0x0011, 0x001a },
+ { 0x0010, 0x0017 },
+ { 0x0012, 0x0001 },
+ { 0x0012, 0x0002 },
+ { 0x0012, 0x0003 },
+ { 0x0011, 0x001b },
+ { 0x0012, 0x0004 },
+ { 0x0012, 0x0005 },
+ { 0x0012, 0x0006 },
+ { 0x0012, 0x0007 },
+ { 0x0012, 0x0008 },
+ { 0x0012, 0x0009 },
+ { 0x0012, 0x000a },
+ { 0x0012, 0x000b },
+ { 0x0012, 0x000c },
+ { 0x0012, 0x000d },
+ { 0x0012, 0x000e },
+ { 0x0012, 0x000f },
+ { 0x0012, 0x0010 },
+ { 0x0012, 0x0011 },
+ { 0x0012, 0x0012 },
+ { 0x0012, 0x0013 },
+ { 0x0012, 0x0014 },
+ { 0x0012, 0x0015 },
+ { 0x0012, 0x0016 },
+ { 0x0012, 0x0017 },
+ { 0x0012, 0x0018 },
+ { 0x0011, 0x001c },
+ { 0x0012, 0x0019 },
+ { 0x0012, 0x001a },
+ { 0x0012, 0x001b },
+ { 0x0012, 0x001c },
+ { 0x0012, 0x001d },
+ { 0x0012, 0x001e },
+ { 0x0012, 0x001f },
+ { 0x0012, 0x0020 },
+ { 0x0012, 0x0021 },
+ { 0x0012, 0x0022 },
+ { 0x0012, 0x0023 },
+ { 0x0012, 0x0024 },
+ { 0x0012, 0x0025 },
+ { 0x0012, 0x0026 },
+ { 0x0012, 0x0027 },
+ { 0x0012, 0x0028 },
+ { 0x0012, 0x0029 },
+ { 0x0012, 0x002a },
+ { 0x0012, 0x002b },
+ { 0x0012, 0x002c },
+ { 0x0012, 0x002d },
+ { 0x0012, 0x002e },
+ { 0x0012, 0x002f },
+ { 0x0012, 0x0030 },
+ { 0x0012, 0x0031 },
+ { 0x0011, 0x001d },
+
+ };
+
+const uint16_t c_aauiLCLDHuffEnc63[181][2] =
+ {
+ { 0x0004, 0x0008 },
+ { 0x0003, 0x0005 },
+ { 0x0002, 0x0003 },
+ { 0x0004, 0x0009 },
+ { 0x0005, 0x000c },
+ { 0x0005, 0x000d },
+ { 0x0005, 0x000e },
+ { 0x0005, 0x000f },
+ { 0x0006, 0x000c },
+ { 0x0006, 0x000d },
+ { 0x0006, 0x000e },
+ { 0x0006, 0x000f },
+ { 0x0006, 0x0010 },
+ { 0x0006, 0x0011 },
+ { 0x0006, 0x0012 },
+ { 0x0006, 0x0013 },
+ { 0x0006, 0x0014 },
+ { 0x0006, 0x0015 },
+ { 0x0006, 0x0016 },
+ { 0x0006, 0x0017 },
+ { 0x0007, 0x000b },
+ { 0x0007, 0x000c },
+ { 0x0007, 0x000d },
+ { 0x0007, 0x000e },
+ { 0x0007, 0x000f },
+ { 0x0007, 0x0010 },
+ { 0x0007, 0x0011 },
+ { 0x0007, 0x0012 },
+ { 0x0007, 0x0013 },
+ { 0x0007, 0x0014 },
+ { 0x0007, 0x0015 },
+ { 0x0007, 0x0016 },
+ { 0x0007, 0x0017 },
+ { 0x0008, 0x000c },
+ { 0x0008, 0x000d },
+ { 0x0008, 0x000e },
+ { 0x0008, 0x000f },
+ { 0x0008, 0x0010 },
+ { 0x0008, 0x0011 },
+ { 0x0008, 0x0012 },
+ { 0x0008, 0x0013 },
+ { 0x0008, 0x0014 },
+ { 0x0008, 0x0015 },
+ { 0x0009, 0x0008 },
+ { 0x0009, 0x0009 },
+ { 0x0009, 0x000a },
+ { 0x0009, 0x000b },
+ { 0x0009, 0x000c },
+ { 0x0009, 0x000d },
+ { 0x0009, 0x000e },
+ { 0x0009, 0x000f },
+ { 0x0009, 0x0010 },
+ { 0x0009, 0x0011 },
+ { 0x0009, 0x0012 },
+ { 0x0009, 0x0013 },
+ { 0x0009, 0x0014 },
+ { 0x0009, 0x0015 },
+ { 0x000a, 0x0007 },
+ { 0x0009, 0x0016 },
+ { 0x0009, 0x0017 },
+ { 0x000a, 0x0008 },
+ { 0x000a, 0x0009 },
+ { 0x000a, 0x000a },
+ { 0x000a, 0x000b },
+ { 0x000a, 0x000c },
+ { 0x000a, 0x000d },
+ { 0x000a, 0x000e },
+ { 0x000b, 0x0008 },
+ { 0x000b, 0x0009 },
+ { 0x000b, 0x000a },
+ { 0x000a, 0x000f },
+ { 0x000b, 0x000b },
+ { 0x000b, 0x000c },
+ { 0x000b, 0x000d },
+ { 0x000c, 0x0009 },
+ { 0x000c, 0x000a },
+ { 0x000c, 0x000b },
+ { 0x000c, 0x000c },
+ { 0x000c, 0x000d },
+ { 0x000c, 0x000e },
+ { 0x000c, 0x000f },
+ { 0x000d, 0x0008 },
+ { 0x000d, 0x0009 },
+ { 0x000d, 0x000a },
+ { 0x000d, 0x000b },
+ { 0x000d, 0x000c },
+ { 0x000d, 0x000d },
+ { 0x000d, 0x000e },
+ { 0x000d, 0x000f },
+ { 0x000d, 0x0010 },
+ { 0x000d, 0x0011 },
+ { 0x000e, 0x0007 },
+ { 0x000e, 0x0008 },
+ { 0x000e, 0x0009 },
+ { 0x000e, 0x000a },
+ { 0x000e, 0x000b },
+ { 0x000e, 0x000c },
+ { 0x000e, 0x000d },
+ { 0x000e, 0x000e },
+ { 0x000e, 0x000f },
+ { 0x000f, 0x0008 },
+ { 0x000f, 0x0009 },
+ { 0x000f, 0x000a },
+ { 0x000f, 0x000b },
+ { 0x000f, 0x000c },
+ { 0x0010, 0x0009 },
+ { 0x0010, 0x000a },
+ { 0x000f, 0x000d },
+ { 0x0010, 0x000b },
+ { 0x0010, 0x000c },
+ { 0x0010, 0x000d },
+ { 0x0011, 0x000e },
+ { 0x0011, 0x000f },
+ { 0x0010, 0x000e },
+ { 0x0011, 0x0010 },
+ { 0x0011, 0x0011 },
+ { 0x0012, 0x0014 },
+ { 0x0014, 0x0000 },
+ { 0x0010, 0x000f },
+ { 0x0012, 0x0015 },
+ { 0x0012, 0x0016 },
+ { 0x0014, 0x0001 },
+ { 0x0012, 0x0017 },
+ { 0x0012, 0x0018 },
+ { 0x0012, 0x0019 },
+ { 0x0013, 0x0010 },
+ { 0x0012, 0x001a },
+ { 0x0014, 0x0002 },
+ { 0x0012, 0x001b },
+ { 0x0014, 0x0003 },
+ { 0x0014, 0x0004 },
+ { 0x0014, 0x0005 },
+ { 0x0013, 0x0011 },
+ { 0x0014, 0x0006 },
+ { 0x0013, 0x0012 },
+ { 0x0014, 0x0007 },
+ { 0x0014, 0x0008 },
+ { 0x0014, 0x0009 },
+ { 0x0014, 0x000a },
+ { 0x0014, 0x000b },
+ { 0x0014, 0x000c },
+ { 0x0014, 0x000d },
+ { 0x0014, 0x000e },
+ { 0x0013, 0x0013 },
+ { 0x0014, 0x000f },
+ { 0x0014, 0x0010 },
+ { 0x0014, 0x0011 },
+ { 0x0014, 0x0012 },
+ { 0x0014, 0x0013 },
+ { 0x0014, 0x0014 },
+ { 0x0014, 0x0015 },
+ { 0x0014, 0x0016 },
+ { 0x0014, 0x0017 },
+ { 0x0014, 0x0018 },
+ { 0x0014, 0x0019 },
+ { 0x0014, 0x001a },
+ { 0x0014, 0x001b },
+ { 0x0014, 0x001c },
+ { 0x0014, 0x001d },
+ { 0x0014, 0x001e },
+ { 0x0014, 0x001f },
+ { 0x0013, 0x0014 },
+ { 0x0013, 0x0015 },
+ { 0x0013, 0x0016 },
+ { 0x0013, 0x0017 },
+ { 0x0013, 0x0018 },
+ { 0x0013, 0x0019 },
+ { 0x0013, 0x001a },
+ { 0x0013, 0x001b },
+ { 0x0013, 0x001c },
+ { 0x0013, 0x001d },
+ { 0x0013, 0x001e },
+ { 0x0013, 0x001f },
+ { 0x0013, 0x0020 },
+ { 0x0013, 0x0021 },
+ { 0x0013, 0x0022 },
+ { 0x0013, 0x0023 },
+ { 0x0013, 0x0024 },
+ { 0x0013, 0x0025 },
+ { 0x0013, 0x0026 },
+ { 0x0013, 0x0027 },
+
+ };
+
+const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] =
+ {
+ NULL,
+ c_aauiLCLDHuffEnc1,
+ c_aauiLCLDHuffEnc2,
+ c_aauiLCLDHuffEnc3,
+ c_aauiLCLDHuffEnc4,
+ c_aauiLCLDHuffEnc5,
+ c_aauiLCLDHuffEnc6,
+ c_aauiLCLDHuffEnc7,
+ c_aauiLCLDHuffEnc8,
+ c_aauiLCLDHuffEnc9,
+ c_aauiLCLDHuffEnc10,
+ c_aauiLCLDHuffEnc11,
+ c_aauiLCLDHuffEnc12,
+ c_aauiLCLDHuffEnc13,
+ c_aauiLCLDHuffEnc14,
+ c_aauiLCLDHuffEnc15,
+ c_aauiLCLDHuffEnc16,
+ c_aauiLCLDHuffEnc17,
+ c_aauiLCLDHuffEnc18,
+ c_aauiLCLDHuffEnc19,
+ c_aauiLCLDHuffEnc20,
+ c_aauiLCLDHuffEnc21,
+ c_aauiLCLDHuffEnc22,
+ c_aauiLCLDHuffEnc23,
+ c_aauiLCLDHuffEnc24,
+ c_aauiLCLDHuffEnc25,
+ c_aauiLCLDHuffEnc26,
+ c_aauiLCLDHuffEnc27,
+ c_aauiLCLDHuffEnc28,
+ c_aauiLCLDHuffEnc29,
+ c_aauiLCLDHuffEnc30,
+ c_aauiLCLDHuffEnc31,
+ NULL,
+ c_aauiLCLDHuffEnc33,
+ c_aauiLCLDHuffEnc34,
+ c_aauiLCLDHuffEnc35,
+ c_aauiLCLDHuffEnc36,
+ c_aauiLCLDHuffEnc37,
+ c_aauiLCLDHuffEnc38,
+ c_aauiLCLDHuffEnc39,
+ c_aauiLCLDHuffEnc40,
+ c_aauiLCLDHuffEnc41,
+ c_aauiLCLDHuffEnc42,
+ c_aauiLCLDHuffEnc43,
+ c_aauiLCLDHuffEnc44,
+ c_aauiLCLDHuffEnc45,
+ c_aauiLCLDHuffEnc46,
+ c_aauiLCLDHuffEnc47,
+ c_aauiLCLDHuffEnc48,
+ c_aauiLCLDHuffEnc49,
+ c_aauiLCLDHuffEnc50,
+ c_aauiLCLDHuffEnc51,
+ c_aauiLCLDHuffEnc52,
+ c_aauiLCLDHuffEnc53,
+ c_aauiLCLDHuffEnc54,
+ c_aauiLCLDHuffEnc55,
+ c_aauiLCLDHuffEnc56,
+ c_aauiLCLDHuffEnc57,
+ c_aauiLCLDHuffEnc58,
+ c_aauiLCLDHuffEnc59,
+ c_aauiLCLDHuffEnc60,
+ c_aauiLCLDHuffEnc61,
+ c_aauiLCLDHuffEnc62,
+ c_aauiLCLDHuffEnc63,
+ };
+
+const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100,
+ 169, 196, 289, 324, 400, 576, 729, 729, 28, 29,
+ 32, 37, 39, 46, 55, 65, 77, 91, 109, 129,
+ 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81,
+ 100, 169, 196, 289, 324, 400, 576, 729, 729, 28,
+ 29, 32, 37, 39, 46, 55, 65, 77, 91, 109,
+ 129, 153, 181 };
+#ifdef USE_DEMOD_TABLES
+const int32_t c_aaiHuffDemod1[16][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+};
+
+const int32_t c_aaiHuffDemod2[16][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+};
+
+const int32_t c_aaiHuffDemod3[25][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+};
+
+const int32_t c_aaiHuffDemod4[36][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+};
+
+const int32_t c_aaiHuffDemod5[36][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+};
+
+const int32_t c_aaiHuffDemod6[49][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+};
+
+const int32_t c_aaiHuffDemod7[64][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+};
+
+const int32_t c_aaiHuffDemod8[81][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+};
+
+const int32_t c_aaiHuffDemod9[100][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+};
+
+const int32_t c_aaiHuffDemod10[169][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+};
+
+const int32_t c_aaiHuffDemod11[196][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+};
+
+const int32_t c_aaiHuffDemod12[289][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+};
+
+const int32_t c_aaiHuffDemod13[324][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 0,
+ 17,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 17,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 2,
+ 17,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 3,
+ 17,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 4,
+ 17,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 5,
+ 17,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 6,
+ 17,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 7,
+ 17,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 8,
+ 17,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 9,
+ 17,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 10,
+ 17,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 11,
+ 17,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 12,
+ 17,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 13,
+ 17,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 14,
+ 17,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 15,
+ 17,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+ 16,
+ 17,
+ 17,
+ 0,
+ 17,
+ 1,
+ 17,
+ 2,
+ 17,
+ 3,
+ 17,
+ 4,
+ 17,
+ 5,
+ 17,
+ 6,
+ 17,
+ 7,
+ 17,
+ 8,
+ 17,
+ 9,
+ 17,
+ 10,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 13,
+ 17,
+ 14,
+ 17,
+ 15,
+ 17,
+ 16,
+ 17,
+ 17,
+};
+
+const int32_t c_aaiHuffDemod14[400][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 0,
+ 17,
+ 0,
+ 18,
+ 0,
+ 19,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 19,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 2,
+ 17,
+ 2,
+ 18,
+ 2,
+ 19,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 3,
+ 17,
+ 3,
+ 18,
+ 3,
+ 19,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 4,
+ 17,
+ 4,
+ 18,
+ 4,
+ 19,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 5,
+ 17,
+ 5,
+ 18,
+ 5,
+ 19,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 6,
+ 17,
+ 6,
+ 18,
+ 6,
+ 19,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 7,
+ 17,
+ 7,
+ 18,
+ 7,
+ 19,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 8,
+ 17,
+ 8,
+ 18,
+ 8,
+ 19,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 9,
+ 17,
+ 9,
+ 18,
+ 9,
+ 19,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 10,
+ 17,
+ 10,
+ 18,
+ 10,
+ 19,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 11,
+ 17,
+ 11,
+ 18,
+ 11,
+ 19,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 12,
+ 17,
+ 12,
+ 18,
+ 12,
+ 19,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 13,
+ 17,
+ 13,
+ 18,
+ 13,
+ 19,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 14,
+ 17,
+ 14,
+ 18,
+ 14,
+ 19,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 15,
+ 17,
+ 15,
+ 18,
+ 15,
+ 19,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+ 16,
+ 17,
+ 16,
+ 18,
+ 16,
+ 19,
+ 17,
+ 0,
+ 17,
+ 1,
+ 17,
+ 2,
+ 17,
+ 3,
+ 17,
+ 4,
+ 17,
+ 5,
+ 17,
+ 6,
+ 17,
+ 7,
+ 17,
+ 8,
+ 17,
+ 9,
+ 17,
+ 10,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 13,
+ 17,
+ 14,
+ 17,
+ 15,
+ 17,
+ 16,
+ 17,
+ 17,
+ 17,
+ 18,
+ 17,
+ 19,
+ 18,
+ 0,
+ 18,
+ 1,
+ 18,
+ 2,
+ 18,
+ 3,
+ 18,
+ 4,
+ 18,
+ 5,
+ 18,
+ 6,
+ 18,
+ 7,
+ 18,
+ 8,
+ 18,
+ 9,
+ 18,
+ 10,
+ 18,
+ 11,
+ 18,
+ 12,
+ 18,
+ 13,
+ 18,
+ 14,
+ 18,
+ 15,
+ 18,
+ 16,
+ 18,
+ 17,
+ 18,
+ 18,
+ 18,
+ 19,
+ 19,
+ 0,
+ 19,
+ 1,
+ 19,
+ 2,
+ 19,
+ 3,
+ 19,
+ 4,
+ 19,
+ 5,
+ 19,
+ 6,
+ 19,
+ 7,
+ 19,
+ 8,
+ 19,
+ 9,
+ 19,
+ 10,
+ 19,
+ 11,
+ 19,
+ 12,
+ 19,
+ 13,
+ 19,
+ 14,
+ 19,
+ 15,
+ 19,
+ 16,
+ 19,
+ 17,
+ 19,
+ 18,
+ 19,
+ 19,
+};
+
+const int32_t c_aaiHuffDemod15[576][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 0,
+ 17,
+ 0,
+ 18,
+ 0,
+ 19,
+ 0,
+ 20,
+ 0,
+ 21,
+ 0,
+ 22,
+ 0,
+ 23,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 22,
+ 1,
+ 23,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 2,
+ 17,
+ 2,
+ 18,
+ 2,
+ 19,
+ 2,
+ 20,
+ 2,
+ 21,
+ 2,
+ 22,
+ 2,
+ 23,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 3,
+ 17,
+ 3,
+ 18,
+ 3,
+ 19,
+ 3,
+ 20,
+ 3,
+ 21,
+ 3,
+ 22,
+ 3,
+ 23,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 4,
+ 17,
+ 4,
+ 18,
+ 4,
+ 19,
+ 4,
+ 20,
+ 4,
+ 21,
+ 4,
+ 22,
+ 4,
+ 23,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 5,
+ 17,
+ 5,
+ 18,
+ 5,
+ 19,
+ 5,
+ 20,
+ 5,
+ 21,
+ 5,
+ 22,
+ 5,
+ 23,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 6,
+ 17,
+ 6,
+ 18,
+ 6,
+ 19,
+ 6,
+ 20,
+ 6,
+ 21,
+ 6,
+ 22,
+ 6,
+ 23,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 7,
+ 17,
+ 7,
+ 18,
+ 7,
+ 19,
+ 7,
+ 20,
+ 7,
+ 21,
+ 7,
+ 22,
+ 7,
+ 23,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 8,
+ 17,
+ 8,
+ 18,
+ 8,
+ 19,
+ 8,
+ 20,
+ 8,
+ 21,
+ 8,
+ 22,
+ 8,
+ 23,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 9,
+ 17,
+ 9,
+ 18,
+ 9,
+ 19,
+ 9,
+ 20,
+ 9,
+ 21,
+ 9,
+ 22,
+ 9,
+ 23,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 10,
+ 17,
+ 10,
+ 18,
+ 10,
+ 19,
+ 10,
+ 20,
+ 10,
+ 21,
+ 10,
+ 22,
+ 10,
+ 23,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 11,
+ 17,
+ 11,
+ 18,
+ 11,
+ 19,
+ 11,
+ 20,
+ 11,
+ 21,
+ 11,
+ 22,
+ 11,
+ 23,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 12,
+ 17,
+ 12,
+ 18,
+ 12,
+ 19,
+ 12,
+ 20,
+ 12,
+ 21,
+ 12,
+ 22,
+ 12,
+ 23,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 13,
+ 17,
+ 13,
+ 18,
+ 13,
+ 19,
+ 13,
+ 20,
+ 13,
+ 21,
+ 13,
+ 22,
+ 13,
+ 23,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 14,
+ 17,
+ 14,
+ 18,
+ 14,
+ 19,
+ 14,
+ 20,
+ 14,
+ 21,
+ 14,
+ 22,
+ 14,
+ 23,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 15,
+ 17,
+ 15,
+ 18,
+ 15,
+ 19,
+ 15,
+ 20,
+ 15,
+ 21,
+ 15,
+ 22,
+ 15,
+ 23,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+ 16,
+ 17,
+ 16,
+ 18,
+ 16,
+ 19,
+ 16,
+ 20,
+ 16,
+ 21,
+ 16,
+ 22,
+ 16,
+ 23,
+ 17,
+ 0,
+ 17,
+ 1,
+ 17,
+ 2,
+ 17,
+ 3,
+ 17,
+ 4,
+ 17,
+ 5,
+ 17,
+ 6,
+ 17,
+ 7,
+ 17,
+ 8,
+ 17,
+ 9,
+ 17,
+ 10,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 13,
+ 17,
+ 14,
+ 17,
+ 15,
+ 17,
+ 16,
+ 17,
+ 17,
+ 17,
+ 18,
+ 17,
+ 19,
+ 17,
+ 20,
+ 17,
+ 21,
+ 17,
+ 22,
+ 17,
+ 23,
+ 18,
+ 0,
+ 18,
+ 1,
+ 18,
+ 2,
+ 18,
+ 3,
+ 18,
+ 4,
+ 18,
+ 5,
+ 18,
+ 6,
+ 18,
+ 7,
+ 18,
+ 8,
+ 18,
+ 9,
+ 18,
+ 10,
+ 18,
+ 11,
+ 18,
+ 12,
+ 18,
+ 13,
+ 18,
+ 14,
+ 18,
+ 15,
+ 18,
+ 16,
+ 18,
+ 17,
+ 18,
+ 18,
+ 18,
+ 19,
+ 18,
+ 20,
+ 18,
+ 21,
+ 18,
+ 22,
+ 18,
+ 23,
+ 19,
+ 0,
+ 19,
+ 1,
+ 19,
+ 2,
+ 19,
+ 3,
+ 19,
+ 4,
+ 19,
+ 5,
+ 19,
+ 6,
+ 19,
+ 7,
+ 19,
+ 8,
+ 19,
+ 9,
+ 19,
+ 10,
+ 19,
+ 11,
+ 19,
+ 12,
+ 19,
+ 13,
+ 19,
+ 14,
+ 19,
+ 15,
+ 19,
+ 16,
+ 19,
+ 17,
+ 19,
+ 18,
+ 19,
+ 19,
+ 19,
+ 20,
+ 19,
+ 21,
+ 19,
+ 22,
+ 19,
+ 23,
+ 20,
+ 0,
+ 20,
+ 1,
+ 20,
+ 2,
+ 20,
+ 3,
+ 20,
+ 4,
+ 20,
+ 5,
+ 20,
+ 6,
+ 20,
+ 7,
+ 20,
+ 8,
+ 20,
+ 9,
+ 20,
+ 10,
+ 20,
+ 11,
+ 20,
+ 12,
+ 20,
+ 13,
+ 20,
+ 14,
+ 20,
+ 15,
+ 20,
+ 16,
+ 20,
+ 17,
+ 20,
+ 18,
+ 20,
+ 19,
+ 20,
+ 20,
+ 20,
+ 21,
+ 20,
+ 22,
+ 20,
+ 23,
+ 21,
+ 0,
+ 21,
+ 1,
+ 21,
+ 2,
+ 21,
+ 3,
+ 21,
+ 4,
+ 21,
+ 5,
+ 21,
+ 6,
+ 21,
+ 7,
+ 21,
+ 8,
+ 21,
+ 9,
+ 21,
+ 10,
+ 21,
+ 11,
+ 21,
+ 12,
+ 21,
+ 13,
+ 21,
+ 14,
+ 21,
+ 15,
+ 21,
+ 16,
+ 21,
+ 17,
+ 21,
+ 18,
+ 21,
+ 19,
+ 21,
+ 20,
+ 21,
+ 21,
+ 21,
+ 22,
+ 21,
+ 23,
+ 22,
+ 0,
+ 22,
+ 1,
+ 22,
+ 2,
+ 22,
+ 3,
+ 22,
+ 4,
+ 22,
+ 5,
+ 22,
+ 6,
+ 22,
+ 7,
+ 22,
+ 8,
+ 22,
+ 9,
+ 22,
+ 10,
+ 22,
+ 11,
+ 22,
+ 12,
+ 22,
+ 13,
+ 22,
+ 14,
+ 22,
+ 15,
+ 22,
+ 16,
+ 22,
+ 17,
+ 22,
+ 18,
+ 22,
+ 19,
+ 22,
+ 20,
+ 22,
+ 21,
+ 22,
+ 22,
+ 22,
+ 23,
+ 23,
+ 0,
+ 23,
+ 1,
+ 23,
+ 2,
+ 23,
+ 3,
+ 23,
+ 4,
+ 23,
+ 5,
+ 23,
+ 6,
+ 23,
+ 7,
+ 23,
+ 8,
+ 23,
+ 9,
+ 23,
+ 10,
+ 23,
+ 11,
+ 23,
+ 12,
+ 23,
+ 13,
+ 23,
+ 14,
+ 23,
+ 15,
+ 23,
+ 16,
+ 23,
+ 17,
+ 23,
+ 18,
+ 23,
+ 19,
+ 23,
+ 20,
+ 23,
+ 21,
+ 23,
+ 22,
+ 23,
+ 23,
+};
+
+const int32_t c_aaiHuffDemod16[729][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 0,
+ 17,
+ 0,
+ 18,
+ 0,
+ 19,
+ 0,
+ 20,
+ 0,
+ 21,
+ 0,
+ 22,
+ 0,
+ 23,
+ 0,
+ 24,
+ 0,
+ 25,
+ 0,
+ 26,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 22,
+ 1,
+ 23,
+ 1,
+ 24,
+ 1,
+ 25,
+ 1,
+ 26,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 2,
+ 17,
+ 2,
+ 18,
+ 2,
+ 19,
+ 2,
+ 20,
+ 2,
+ 21,
+ 2,
+ 22,
+ 2,
+ 23,
+ 2,
+ 24,
+ 2,
+ 25,
+ 2,
+ 26,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 3,
+ 17,
+ 3,
+ 18,
+ 3,
+ 19,
+ 3,
+ 20,
+ 3,
+ 21,
+ 3,
+ 22,
+ 3,
+ 23,
+ 3,
+ 24,
+ 3,
+ 25,
+ 3,
+ 26,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 4,
+ 17,
+ 4,
+ 18,
+ 4,
+ 19,
+ 4,
+ 20,
+ 4,
+ 21,
+ 4,
+ 22,
+ 4,
+ 23,
+ 4,
+ 24,
+ 4,
+ 25,
+ 4,
+ 26,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 5,
+ 17,
+ 5,
+ 18,
+ 5,
+ 19,
+ 5,
+ 20,
+ 5,
+ 21,
+ 5,
+ 22,
+ 5,
+ 23,
+ 5,
+ 24,
+ 5,
+ 25,
+ 5,
+ 26,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 6,
+ 17,
+ 6,
+ 18,
+ 6,
+ 19,
+ 6,
+ 20,
+ 6,
+ 21,
+ 6,
+ 22,
+ 6,
+ 23,
+ 6,
+ 24,
+ 6,
+ 25,
+ 6,
+ 26,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 7,
+ 17,
+ 7,
+ 18,
+ 7,
+ 19,
+ 7,
+ 20,
+ 7,
+ 21,
+ 7,
+ 22,
+ 7,
+ 23,
+ 7,
+ 24,
+ 7,
+ 25,
+ 7,
+ 26,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 8,
+ 17,
+ 8,
+ 18,
+ 8,
+ 19,
+ 8,
+ 20,
+ 8,
+ 21,
+ 8,
+ 22,
+ 8,
+ 23,
+ 8,
+ 24,
+ 8,
+ 25,
+ 8,
+ 26,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 9,
+ 17,
+ 9,
+ 18,
+ 9,
+ 19,
+ 9,
+ 20,
+ 9,
+ 21,
+ 9,
+ 22,
+ 9,
+ 23,
+ 9,
+ 24,
+ 9,
+ 25,
+ 9,
+ 26,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 10,
+ 17,
+ 10,
+ 18,
+ 10,
+ 19,
+ 10,
+ 20,
+ 10,
+ 21,
+ 10,
+ 22,
+ 10,
+ 23,
+ 10,
+ 24,
+ 10,
+ 25,
+ 10,
+ 26,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 11,
+ 17,
+ 11,
+ 18,
+ 11,
+ 19,
+ 11,
+ 20,
+ 11,
+ 21,
+ 11,
+ 22,
+ 11,
+ 23,
+ 11,
+ 24,
+ 11,
+ 25,
+ 11,
+ 26,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 12,
+ 17,
+ 12,
+ 18,
+ 12,
+ 19,
+ 12,
+ 20,
+ 12,
+ 21,
+ 12,
+ 22,
+ 12,
+ 23,
+ 12,
+ 24,
+ 12,
+ 25,
+ 12,
+ 26,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 13,
+ 17,
+ 13,
+ 18,
+ 13,
+ 19,
+ 13,
+ 20,
+ 13,
+ 21,
+ 13,
+ 22,
+ 13,
+ 23,
+ 13,
+ 24,
+ 13,
+ 25,
+ 13,
+ 26,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 14,
+ 17,
+ 14,
+ 18,
+ 14,
+ 19,
+ 14,
+ 20,
+ 14,
+ 21,
+ 14,
+ 22,
+ 14,
+ 23,
+ 14,
+ 24,
+ 14,
+ 25,
+ 14,
+ 26,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 15,
+ 17,
+ 15,
+ 18,
+ 15,
+ 19,
+ 15,
+ 20,
+ 15,
+ 21,
+ 15,
+ 22,
+ 15,
+ 23,
+ 15,
+ 24,
+ 15,
+ 25,
+ 15,
+ 26,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+ 16,
+ 17,
+ 16,
+ 18,
+ 16,
+ 19,
+ 16,
+ 20,
+ 16,
+ 21,
+ 16,
+ 22,
+ 16,
+ 23,
+ 16,
+ 24,
+ 16,
+ 25,
+ 16,
+ 26,
+ 17,
+ 0,
+ 17,
+ 1,
+ 17,
+ 2,
+ 17,
+ 3,
+ 17,
+ 4,
+ 17,
+ 5,
+ 17,
+ 6,
+ 17,
+ 7,
+ 17,
+ 8,
+ 17,
+ 9,
+ 17,
+ 10,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 13,
+ 17,
+ 14,
+ 17,
+ 15,
+ 17,
+ 16,
+ 17,
+ 17,
+ 17,
+ 18,
+ 17,
+ 19,
+ 17,
+ 20,
+ 17,
+ 21,
+ 17,
+ 22,
+ 17,
+ 23,
+ 17,
+ 24,
+ 17,
+ 25,
+ 17,
+ 26,
+ 18,
+ 0,
+ 18,
+ 1,
+ 18,
+ 2,
+ 18,
+ 3,
+ 18,
+ 4,
+ 18,
+ 5,
+ 18,
+ 6,
+ 18,
+ 7,
+ 18,
+ 8,
+ 18,
+ 9,
+ 18,
+ 10,
+ 18,
+ 11,
+ 18,
+ 12,
+ 18,
+ 13,
+ 18,
+ 14,
+ 18,
+ 15,
+ 18,
+ 16,
+ 18,
+ 17,
+ 18,
+ 18,
+ 18,
+ 19,
+ 18,
+ 20,
+ 18,
+ 21,
+ 18,
+ 22,
+ 18,
+ 23,
+ 18,
+ 24,
+ 18,
+ 25,
+ 18,
+ 26,
+ 19,
+ 0,
+ 19,
+ 1,
+ 19,
+ 2,
+ 19,
+ 3,
+ 19,
+ 4,
+ 19,
+ 5,
+ 19,
+ 6,
+ 19,
+ 7,
+ 19,
+ 8,
+ 19,
+ 9,
+ 19,
+ 10,
+ 19,
+ 11,
+ 19,
+ 12,
+ 19,
+ 13,
+ 19,
+ 14,
+ 19,
+ 15,
+ 19,
+ 16,
+ 19,
+ 17,
+ 19,
+ 18,
+ 19,
+ 19,
+ 19,
+ 20,
+ 19,
+ 21,
+ 19,
+ 22,
+ 19,
+ 23,
+ 19,
+ 24,
+ 19,
+ 25,
+ 19,
+ 26,
+ 20,
+ 0,
+ 20,
+ 1,
+ 20,
+ 2,
+ 20,
+ 3,
+ 20,
+ 4,
+ 20,
+ 5,
+ 20,
+ 6,
+ 20,
+ 7,
+ 20,
+ 8,
+ 20,
+ 9,
+ 20,
+ 10,
+ 20,
+ 11,
+ 20,
+ 12,
+ 20,
+ 13,
+ 20,
+ 14,
+ 20,
+ 15,
+ 20,
+ 16,
+ 20,
+ 17,
+ 20,
+ 18,
+ 20,
+ 19,
+ 20,
+ 20,
+ 20,
+ 21,
+ 20,
+ 22,
+ 20,
+ 23,
+ 20,
+ 24,
+ 20,
+ 25,
+ 20,
+ 26,
+ 21,
+ 0,
+ 21,
+ 1,
+ 21,
+ 2,
+ 21,
+ 3,
+ 21,
+ 4,
+ 21,
+ 5,
+ 21,
+ 6,
+ 21,
+ 7,
+ 21,
+ 8,
+ 21,
+ 9,
+ 21,
+ 10,
+ 21,
+ 11,
+ 21,
+ 12,
+ 21,
+ 13,
+ 21,
+ 14,
+ 21,
+ 15,
+ 21,
+ 16,
+ 21,
+ 17,
+ 21,
+ 18,
+ 21,
+ 19,
+ 21,
+ 20,
+ 21,
+ 21,
+ 21,
+ 22,
+ 21,
+ 23,
+ 21,
+ 24,
+ 21,
+ 25,
+ 21,
+ 26,
+ 22,
+ 0,
+ 22,
+ 1,
+ 22,
+ 2,
+ 22,
+ 3,
+ 22,
+ 4,
+ 22,
+ 5,
+ 22,
+ 6,
+ 22,
+ 7,
+ 22,
+ 8,
+ 22,
+ 9,
+ 22,
+ 10,
+ 22,
+ 11,
+ 22,
+ 12,
+ 22,
+ 13,
+ 22,
+ 14,
+ 22,
+ 15,
+ 22,
+ 16,
+ 22,
+ 17,
+ 22,
+ 18,
+ 22,
+ 19,
+ 22,
+ 20,
+ 22,
+ 21,
+ 22,
+ 22,
+ 22,
+ 23,
+ 22,
+ 24,
+ 22,
+ 25,
+ 22,
+ 26,
+ 23,
+ 0,
+ 23,
+ 1,
+ 23,
+ 2,
+ 23,
+ 3,
+ 23,
+ 4,
+ 23,
+ 5,
+ 23,
+ 6,
+ 23,
+ 7,
+ 23,
+ 8,
+ 23,
+ 9,
+ 23,
+ 10,
+ 23,
+ 11,
+ 23,
+ 12,
+ 23,
+ 13,
+ 23,
+ 14,
+ 23,
+ 15,
+ 23,
+ 16,
+ 23,
+ 17,
+ 23,
+ 18,
+ 23,
+ 19,
+ 23,
+ 20,
+ 23,
+ 21,
+ 23,
+ 22,
+ 23,
+ 23,
+ 23,
+ 24,
+ 23,
+ 25,
+ 23,
+ 26,
+ 24,
+ 0,
+ 24,
+ 1,
+ 24,
+ 2,
+ 24,
+ 3,
+ 24,
+ 4,
+ 24,
+ 5,
+ 24,
+ 6,
+ 24,
+ 7,
+ 24,
+ 8,
+ 24,
+ 9,
+ 24,
+ 10,
+ 24,
+ 11,
+ 24,
+ 12,
+ 24,
+ 13,
+ 24,
+ 14,
+ 24,
+ 15,
+ 24,
+ 16,
+ 24,
+ 17,
+ 24,
+ 18,
+ 24,
+ 19,
+ 24,
+ 20,
+ 24,
+ 21,
+ 24,
+ 22,
+ 24,
+ 23,
+ 24,
+ 24,
+ 24,
+ 25,
+ 24,
+ 26,
+ 25,
+ 0,
+ 25,
+ 1,
+ 25,
+ 2,
+ 25,
+ 3,
+ 25,
+ 4,
+ 25,
+ 5,
+ 25,
+ 6,
+ 25,
+ 7,
+ 25,
+ 8,
+ 25,
+ 9,
+ 25,
+ 10,
+ 25,
+ 11,
+ 25,
+ 12,
+ 25,
+ 13,
+ 25,
+ 14,
+ 25,
+ 15,
+ 25,
+ 16,
+ 25,
+ 17,
+ 25,
+ 18,
+ 25,
+ 19,
+ 25,
+ 20,
+ 25,
+ 21,
+ 25,
+ 22,
+ 25,
+ 23,
+ 25,
+ 24,
+ 25,
+ 25,
+ 25,
+ 26,
+ 26,
+ 0,
+ 26,
+ 1,
+ 26,
+ 2,
+ 26,
+ 3,
+ 26,
+ 4,
+ 26,
+ 5,
+ 26,
+ 6,
+ 26,
+ 7,
+ 26,
+ 8,
+ 26,
+ 9,
+ 26,
+ 10,
+ 26,
+ 11,
+ 26,
+ 12,
+ 26,
+ 13,
+ 26,
+ 14,
+ 26,
+ 15,
+ 26,
+ 16,
+ 26,
+ 17,
+ 26,
+ 18,
+ 26,
+ 19,
+ 26,
+ 20,
+ 26,
+ 21,
+ 26,
+ 22,
+ 26,
+ 23,
+ 26,
+ 24,
+ 26,
+ 25,
+ 26,
+ 26,
+};
+
+const int32_t c_aaiHuffDemod17[729][2] = {
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 3,
+ 0,
+ 4,
+ 0,
+ 5,
+ 0,
+ 6,
+ 0,
+ 7,
+ 0,
+ 8,
+ 0,
+ 9,
+ 0,
+ 10,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 13,
+ 0,
+ 14,
+ 0,
+ 15,
+ 0,
+ 16,
+ 0,
+ 17,
+ 0,
+ 18,
+ 0,
+ 19,
+ 0,
+ 20,
+ 0,
+ 21,
+ 0,
+ 22,
+ 0,
+ 23,
+ 0,
+ 24,
+ 0,
+ 25,
+ 0,
+ 26,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 22,
+ 1,
+ 23,
+ 1,
+ 24,
+ 1,
+ 25,
+ 1,
+ 26,
+ 2,
+ 0,
+ 2,
+ 1,
+ 2,
+ 2,
+ 2,
+ 3,
+ 2,
+ 4,
+ 2,
+ 5,
+ 2,
+ 6,
+ 2,
+ 7,
+ 2,
+ 8,
+ 2,
+ 9,
+ 2,
+ 10,
+ 2,
+ 11,
+ 2,
+ 12,
+ 2,
+ 13,
+ 2,
+ 14,
+ 2,
+ 15,
+ 2,
+ 16,
+ 2,
+ 17,
+ 2,
+ 18,
+ 2,
+ 19,
+ 2,
+ 20,
+ 2,
+ 21,
+ 2,
+ 22,
+ 2,
+ 23,
+ 2,
+ 24,
+ 2,
+ 25,
+ 2,
+ 26,
+ 3,
+ 0,
+ 3,
+ 1,
+ 3,
+ 2,
+ 3,
+ 3,
+ 3,
+ 4,
+ 3,
+ 5,
+ 3,
+ 6,
+ 3,
+ 7,
+ 3,
+ 8,
+ 3,
+ 9,
+ 3,
+ 10,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 13,
+ 3,
+ 14,
+ 3,
+ 15,
+ 3,
+ 16,
+ 3,
+ 17,
+ 3,
+ 18,
+ 3,
+ 19,
+ 3,
+ 20,
+ 3,
+ 21,
+ 3,
+ 22,
+ 3,
+ 23,
+ 3,
+ 24,
+ 3,
+ 25,
+ 3,
+ 26,
+ 4,
+ 0,
+ 4,
+ 1,
+ 4,
+ 2,
+ 4,
+ 3,
+ 4,
+ 4,
+ 4,
+ 5,
+ 4,
+ 6,
+ 4,
+ 7,
+ 4,
+ 8,
+ 4,
+ 9,
+ 4,
+ 10,
+ 4,
+ 11,
+ 4,
+ 12,
+ 4,
+ 13,
+ 4,
+ 14,
+ 4,
+ 15,
+ 4,
+ 16,
+ 4,
+ 17,
+ 4,
+ 18,
+ 4,
+ 19,
+ 4,
+ 20,
+ 4,
+ 21,
+ 4,
+ 22,
+ 4,
+ 23,
+ 4,
+ 24,
+ 4,
+ 25,
+ 4,
+ 26,
+ 5,
+ 0,
+ 5,
+ 1,
+ 5,
+ 2,
+ 5,
+ 3,
+ 5,
+ 4,
+ 5,
+ 5,
+ 5,
+ 6,
+ 5,
+ 7,
+ 5,
+ 8,
+ 5,
+ 9,
+ 5,
+ 10,
+ 5,
+ 11,
+ 5,
+ 12,
+ 5,
+ 13,
+ 5,
+ 14,
+ 5,
+ 15,
+ 5,
+ 16,
+ 5,
+ 17,
+ 5,
+ 18,
+ 5,
+ 19,
+ 5,
+ 20,
+ 5,
+ 21,
+ 5,
+ 22,
+ 5,
+ 23,
+ 5,
+ 24,
+ 5,
+ 25,
+ 5,
+ 26,
+ 6,
+ 0,
+ 6,
+ 1,
+ 6,
+ 2,
+ 6,
+ 3,
+ 6,
+ 4,
+ 6,
+ 5,
+ 6,
+ 6,
+ 6,
+ 7,
+ 6,
+ 8,
+ 6,
+ 9,
+ 6,
+ 10,
+ 6,
+ 11,
+ 6,
+ 12,
+ 6,
+ 13,
+ 6,
+ 14,
+ 6,
+ 15,
+ 6,
+ 16,
+ 6,
+ 17,
+ 6,
+ 18,
+ 6,
+ 19,
+ 6,
+ 20,
+ 6,
+ 21,
+ 6,
+ 22,
+ 6,
+ 23,
+ 6,
+ 24,
+ 6,
+ 25,
+ 6,
+ 26,
+ 7,
+ 0,
+ 7,
+ 1,
+ 7,
+ 2,
+ 7,
+ 3,
+ 7,
+ 4,
+ 7,
+ 5,
+ 7,
+ 6,
+ 7,
+ 7,
+ 7,
+ 8,
+ 7,
+ 9,
+ 7,
+ 10,
+ 7,
+ 11,
+ 7,
+ 12,
+ 7,
+ 13,
+ 7,
+ 14,
+ 7,
+ 15,
+ 7,
+ 16,
+ 7,
+ 17,
+ 7,
+ 18,
+ 7,
+ 19,
+ 7,
+ 20,
+ 7,
+ 21,
+ 7,
+ 22,
+ 7,
+ 23,
+ 7,
+ 24,
+ 7,
+ 25,
+ 7,
+ 26,
+ 8,
+ 0,
+ 8,
+ 1,
+ 8,
+ 2,
+ 8,
+ 3,
+ 8,
+ 4,
+ 8,
+ 5,
+ 8,
+ 6,
+ 8,
+ 7,
+ 8,
+ 8,
+ 8,
+ 9,
+ 8,
+ 10,
+ 8,
+ 11,
+ 8,
+ 12,
+ 8,
+ 13,
+ 8,
+ 14,
+ 8,
+ 15,
+ 8,
+ 16,
+ 8,
+ 17,
+ 8,
+ 18,
+ 8,
+ 19,
+ 8,
+ 20,
+ 8,
+ 21,
+ 8,
+ 22,
+ 8,
+ 23,
+ 8,
+ 24,
+ 8,
+ 25,
+ 8,
+ 26,
+ 9,
+ 0,
+ 9,
+ 1,
+ 9,
+ 2,
+ 9,
+ 3,
+ 9,
+ 4,
+ 9,
+ 5,
+ 9,
+ 6,
+ 9,
+ 7,
+ 9,
+ 8,
+ 9,
+ 9,
+ 9,
+ 10,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 13,
+ 9,
+ 14,
+ 9,
+ 15,
+ 9,
+ 16,
+ 9,
+ 17,
+ 9,
+ 18,
+ 9,
+ 19,
+ 9,
+ 20,
+ 9,
+ 21,
+ 9,
+ 22,
+ 9,
+ 23,
+ 9,
+ 24,
+ 9,
+ 25,
+ 9,
+ 26,
+ 10,
+ 0,
+ 10,
+ 1,
+ 10,
+ 2,
+ 10,
+ 3,
+ 10,
+ 4,
+ 10,
+ 5,
+ 10,
+ 6,
+ 10,
+ 7,
+ 10,
+ 8,
+ 10,
+ 9,
+ 10,
+ 10,
+ 10,
+ 11,
+ 10,
+ 12,
+ 10,
+ 13,
+ 10,
+ 14,
+ 10,
+ 15,
+ 10,
+ 16,
+ 10,
+ 17,
+ 10,
+ 18,
+ 10,
+ 19,
+ 10,
+ 20,
+ 10,
+ 21,
+ 10,
+ 22,
+ 10,
+ 23,
+ 10,
+ 24,
+ 10,
+ 25,
+ 10,
+ 26,
+ 11,
+ 0,
+ 11,
+ 1,
+ 11,
+ 2,
+ 11,
+ 3,
+ 11,
+ 4,
+ 11,
+ 5,
+ 11,
+ 6,
+ 11,
+ 7,
+ 11,
+ 8,
+ 11,
+ 9,
+ 11,
+ 10,
+ 11,
+ 11,
+ 11,
+ 12,
+ 11,
+ 13,
+ 11,
+ 14,
+ 11,
+ 15,
+ 11,
+ 16,
+ 11,
+ 17,
+ 11,
+ 18,
+ 11,
+ 19,
+ 11,
+ 20,
+ 11,
+ 21,
+ 11,
+ 22,
+ 11,
+ 23,
+ 11,
+ 24,
+ 11,
+ 25,
+ 11,
+ 26,
+ 12,
+ 0,
+ 12,
+ 1,
+ 12,
+ 2,
+ 12,
+ 3,
+ 12,
+ 4,
+ 12,
+ 5,
+ 12,
+ 6,
+ 12,
+ 7,
+ 12,
+ 8,
+ 12,
+ 9,
+ 12,
+ 10,
+ 12,
+ 11,
+ 12,
+ 12,
+ 12,
+ 13,
+ 12,
+ 14,
+ 12,
+ 15,
+ 12,
+ 16,
+ 12,
+ 17,
+ 12,
+ 18,
+ 12,
+ 19,
+ 12,
+ 20,
+ 12,
+ 21,
+ 12,
+ 22,
+ 12,
+ 23,
+ 12,
+ 24,
+ 12,
+ 25,
+ 12,
+ 26,
+ 13,
+ 0,
+ 13,
+ 1,
+ 13,
+ 2,
+ 13,
+ 3,
+ 13,
+ 4,
+ 13,
+ 5,
+ 13,
+ 6,
+ 13,
+ 7,
+ 13,
+ 8,
+ 13,
+ 9,
+ 13,
+ 10,
+ 13,
+ 11,
+ 13,
+ 12,
+ 13,
+ 13,
+ 13,
+ 14,
+ 13,
+ 15,
+ 13,
+ 16,
+ 13,
+ 17,
+ 13,
+ 18,
+ 13,
+ 19,
+ 13,
+ 20,
+ 13,
+ 21,
+ 13,
+ 22,
+ 13,
+ 23,
+ 13,
+ 24,
+ 13,
+ 25,
+ 13,
+ 26,
+ 14,
+ 0,
+ 14,
+ 1,
+ 14,
+ 2,
+ 14,
+ 3,
+ 14,
+ 4,
+ 14,
+ 5,
+ 14,
+ 6,
+ 14,
+ 7,
+ 14,
+ 8,
+ 14,
+ 9,
+ 14,
+ 10,
+ 14,
+ 11,
+ 14,
+ 12,
+ 14,
+ 13,
+ 14,
+ 14,
+ 14,
+ 15,
+ 14,
+ 16,
+ 14,
+ 17,
+ 14,
+ 18,
+ 14,
+ 19,
+ 14,
+ 20,
+ 14,
+ 21,
+ 14,
+ 22,
+ 14,
+ 23,
+ 14,
+ 24,
+ 14,
+ 25,
+ 14,
+ 26,
+ 15,
+ 0,
+ 15,
+ 1,
+ 15,
+ 2,
+ 15,
+ 3,
+ 15,
+ 4,
+ 15,
+ 5,
+ 15,
+ 6,
+ 15,
+ 7,
+ 15,
+ 8,
+ 15,
+ 9,
+ 15,
+ 10,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 13,
+ 15,
+ 14,
+ 15,
+ 15,
+ 15,
+ 16,
+ 15,
+ 17,
+ 15,
+ 18,
+ 15,
+ 19,
+ 15,
+ 20,
+ 15,
+ 21,
+ 15,
+ 22,
+ 15,
+ 23,
+ 15,
+ 24,
+ 15,
+ 25,
+ 15,
+ 26,
+ 16,
+ 0,
+ 16,
+ 1,
+ 16,
+ 2,
+ 16,
+ 3,
+ 16,
+ 4,
+ 16,
+ 5,
+ 16,
+ 6,
+ 16,
+ 7,
+ 16,
+ 8,
+ 16,
+ 9,
+ 16,
+ 10,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 13,
+ 16,
+ 14,
+ 16,
+ 15,
+ 16,
+ 16,
+ 16,
+ 17,
+ 16,
+ 18,
+ 16,
+ 19,
+ 16,
+ 20,
+ 16,
+ 21,
+ 16,
+ 22,
+ 16,
+ 23,
+ 16,
+ 24,
+ 16,
+ 25,
+ 16,
+ 26,
+ 17,
+ 0,
+ 17,
+ 1,
+ 17,
+ 2,
+ 17,
+ 3,
+ 17,
+ 4,
+ 17,
+ 5,
+ 17,
+ 6,
+ 17,
+ 7,
+ 17,
+ 8,
+ 17,
+ 9,
+ 17,
+ 10,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 13,
+ 17,
+ 14,
+ 17,
+ 15,
+ 17,
+ 16,
+ 17,
+ 17,
+ 17,
+ 18,
+ 17,
+ 19,
+ 17,
+ 20,
+ 17,
+ 21,
+ 17,
+ 22,
+ 17,
+ 23,
+ 17,
+ 24,
+ 17,
+ 25,
+ 17,
+ 26,
+ 18,
+ 0,
+ 18,
+ 1,
+ 18,
+ 2,
+ 18,
+ 3,
+ 18,
+ 4,
+ 18,
+ 5,
+ 18,
+ 6,
+ 18,
+ 7,
+ 18,
+ 8,
+ 18,
+ 9,
+ 18,
+ 10,
+ 18,
+ 11,
+ 18,
+ 12,
+ 18,
+ 13,
+ 18,
+ 14,
+ 18,
+ 15,
+ 18,
+ 16,
+ 18,
+ 17,
+ 18,
+ 18,
+ 18,
+ 19,
+ 18,
+ 20,
+ 18,
+ 21,
+ 18,
+ 22,
+ 18,
+ 23,
+ 18,
+ 24,
+ 18,
+ 25,
+ 18,
+ 26,
+ 19,
+ 0,
+ 19,
+ 1,
+ 19,
+ 2,
+ 19,
+ 3,
+ 19,
+ 4,
+ 19,
+ 5,
+ 19,
+ 6,
+ 19,
+ 7,
+ 19,
+ 8,
+ 19,
+ 9,
+ 19,
+ 10,
+ 19,
+ 11,
+ 19,
+ 12,
+ 19,
+ 13,
+ 19,
+ 14,
+ 19,
+ 15,
+ 19,
+ 16,
+ 19,
+ 17,
+ 19,
+ 18,
+ 19,
+ 19,
+ 19,
+ 20,
+ 19,
+ 21,
+ 19,
+ 22,
+ 19,
+ 23,
+ 19,
+ 24,
+ 19,
+ 25,
+ 19,
+ 26,
+ 20,
+ 0,
+ 20,
+ 1,
+ 20,
+ 2,
+ 20,
+ 3,
+ 20,
+ 4,
+ 20,
+ 5,
+ 20,
+ 6,
+ 20,
+ 7,
+ 20,
+ 8,
+ 20,
+ 9,
+ 20,
+ 10,
+ 20,
+ 11,
+ 20,
+ 12,
+ 20,
+ 13,
+ 20,
+ 14,
+ 20,
+ 15,
+ 20,
+ 16,
+ 20,
+ 17,
+ 20,
+ 18,
+ 20,
+ 19,
+ 20,
+ 20,
+ 20,
+ 21,
+ 20,
+ 22,
+ 20,
+ 23,
+ 20,
+ 24,
+ 20,
+ 25,
+ 20,
+ 26,
+ 21,
+ 0,
+ 21,
+ 1,
+ 21,
+ 2,
+ 21,
+ 3,
+ 21,
+ 4,
+ 21,
+ 5,
+ 21,
+ 6,
+ 21,
+ 7,
+ 21,
+ 8,
+ 21,
+ 9,
+ 21,
+ 10,
+ 21,
+ 11,
+ 21,
+ 12,
+ 21,
+ 13,
+ 21,
+ 14,
+ 21,
+ 15,
+ 21,
+ 16,
+ 21,
+ 17,
+ 21,
+ 18,
+ 21,
+ 19,
+ 21,
+ 20,
+ 21,
+ 21,
+ 21,
+ 22,
+ 21,
+ 23,
+ 21,
+ 24,
+ 21,
+ 25,
+ 21,
+ 26,
+ 22,
+ 0,
+ 22,
+ 1,
+ 22,
+ 2,
+ 22,
+ 3,
+ 22,
+ 4,
+ 22,
+ 5,
+ 22,
+ 6,
+ 22,
+ 7,
+ 22,
+ 8,
+ 22,
+ 9,
+ 22,
+ 10,
+ 22,
+ 11,
+ 22,
+ 12,
+ 22,
+ 13,
+ 22,
+ 14,
+ 22,
+ 15,
+ 22,
+ 16,
+ 22,
+ 17,
+ 22,
+ 18,
+ 22,
+ 19,
+ 22,
+ 20,
+ 22,
+ 21,
+ 22,
+ 22,
+ 22,
+ 23,
+ 22,
+ 24,
+ 22,
+ 25,
+ 22,
+ 26,
+ 23,
+ 0,
+ 23,
+ 1,
+ 23,
+ 2,
+ 23,
+ 3,
+ 23,
+ 4,
+ 23,
+ 5,
+ 23,
+ 6,
+ 23,
+ 7,
+ 23,
+ 8,
+ 23,
+ 9,
+ 23,
+ 10,
+ 23,
+ 11,
+ 23,
+ 12,
+ 23,
+ 13,
+ 23,
+ 14,
+ 23,
+ 15,
+ 23,
+ 16,
+ 23,
+ 17,
+ 23,
+ 18,
+ 23,
+ 19,
+ 23,
+ 20,
+ 23,
+ 21,
+ 23,
+ 22,
+ 23,
+ 23,
+ 23,
+ 24,
+ 23,
+ 25,
+ 23,
+ 26,
+ 24,
+ 0,
+ 24,
+ 1,
+ 24,
+ 2,
+ 24,
+ 3,
+ 24,
+ 4,
+ 24,
+ 5,
+ 24,
+ 6,
+ 24,
+ 7,
+ 24,
+ 8,
+ 24,
+ 9,
+ 24,
+ 10,
+ 24,
+ 11,
+ 24,
+ 12,
+ 24,
+ 13,
+ 24,
+ 14,
+ 24,
+ 15,
+ 24,
+ 16,
+ 24,
+ 17,
+ 24,
+ 18,
+ 24,
+ 19,
+ 24,
+ 20,
+ 24,
+ 21,
+ 24,
+ 22,
+ 24,
+ 23,
+ 24,
+ 24,
+ 24,
+ 25,
+ 24,
+ 26,
+ 25,
+ 0,
+ 25,
+ 1,
+ 25,
+ 2,
+ 25,
+ 3,
+ 25,
+ 4,
+ 25,
+ 5,
+ 25,
+ 6,
+ 25,
+ 7,
+ 25,
+ 8,
+ 25,
+ 9,
+ 25,
+ 10,
+ 25,
+ 11,
+ 25,
+ 12,
+ 25,
+ 13,
+ 25,
+ 14,
+ 25,
+ 15,
+ 25,
+ 16,
+ 25,
+ 17,
+ 25,
+ 18,
+ 25,
+ 19,
+ 25,
+ 20,
+ 25,
+ 21,
+ 25,
+ 22,
+ 25,
+ 23,
+ 25,
+ 24,
+ 25,
+ 25,
+ 25,
+ 26,
+ 26,
+ 0,
+ 26,
+ 1,
+ 26,
+ 2,
+ 26,
+ 3,
+ 26,
+ 4,
+ 26,
+ 5,
+ 26,
+ 6,
+ 26,
+ 7,
+ 26,
+ 8,
+ 26,
+ 9,
+ 26,
+ 10,
+ 26,
+ 11,
+ 26,
+ 12,
+ 26,
+ 13,
+ 26,
+ 14,
+ 26,
+ 15,
+ 26,
+ 16,
+ 26,
+ 17,
+ 26,
+ 18,
+ 26,
+ 19,
+ 26,
+ 20,
+ 26,
+ 21,
+ 26,
+ 22,
+ 26,
+ 23,
+ 26,
+ 24,
+ 26,
+ 25,
+ 26,
+ 26,
+};
+
+const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = {
+ NULL,
+ c_aaiHuffDemod1,
+ c_aaiHuffDemod2,
+ c_aaiHuffDemod3,
+ c_aaiHuffDemod4,
+ c_aaiHuffDemod5,
+ c_aaiHuffDemod6,
+ c_aaiHuffDemod7,
+ c_aaiHuffDemod8,
+ c_aaiHuffDemod9,
+ c_aaiHuffDemod10,
+ c_aaiHuffDemod11,
+ c_aaiHuffDemod12,
+ c_aaiHuffDemod13,
+ c_aaiHuffDemod14,
+ c_aaiHuffDemod15,
+ c_aaiHuffDemod16,
+ c_aaiHuffDemod17,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+#endif
+const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH] = {
+ 0x40,
+ 0x40,
+ 0x3F,
+ 0x3F,
+ 0x3E,
+ 0x3E,
+ 0x3D,
+ 0x3D,
+ 0x3C,
+ 0x3C,
+ 0x3B,
+ 0x3B,
+ 0x3A,
+ 0x3A,
+ 0x39,
+ 0x39,
+ 0x38,
+ 0x38,
+ 0x37,
+ 0x37,
+ 0x37,
+ 0x36,
+ 0x36,
+ 0x35,
+ 0x35,
+ 0x34,
+ 0x34,
+ 0x33,
+ 0x33,
+ 0x33,
+ 0x32,
+ 0x32,
+ 0x31,
+ 0x31,
+ 0x31,
+ 0x30,
+ 0x30,
+ 0x2F,
+ 0x2F,
+ 0x2F,
+ 0x2E,
+ 0x2E,
+ 0x2D,
+ 0x2D,
+ 0x2D,
+ 0x2C,
+ 0x2C,
+ 0x2B,
+ 0x2B,
+ 0x2B,
+ 0x2A,
+ 0x2A,
+ 0x2A,
+ 0x29,
+ 0x29,
+ 0x29,
+ 0x28,
+ 0x28,
+ 0x27,
+ 0x27,
+ 0x27,
+ 0x26,
+ 0x26,
+ 0x26,
+ 0x25,
+ 0x25,
+ 0x25,
+ 0x24,
+ 0x24,
+ 0x24,
+ 0x23,
+ 0x23,
+ 0x23,
+ 0x23,
+ 0x22,
+ 0x22,
+ 0x22,
+ 0x21,
+ 0x21,
+ 0x21,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x1F,
+ 0x1F,
+ 0x1F,
+ 0x1E,
+ 0x1E,
+ 0x1E,
+ 0x1E,
+ 0x1D,
+ 0x1D,
+ 0x1D,
+ 0x1C,
+ 0x1C,
+ 0x1C,
+ 0x1C,
+ 0x1B,
+ 0x1B,
+ 0x1B,
+ 0x1B,
+ 0x1A,
+ 0x1A,
+ 0x1A,
+ 0x1A,
+ 0x19,
+ 0x19,
+ 0x19,
+ 0x19,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x17,
+ 0x17,
+ 0x17,
+ 0x17,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = {
+ 0x40,
+ 0x40,
+ 0x3F,
+ 0x3F,
+ 0x3E,
+ 0x3E,
+ 0x3D,
+ 0x3D,
+ 0x3C,
+ 0x3C,
+ 0x3B,
+ 0x3B,
+ 0x3A,
+ 0x3A,
+ 0x39,
+ 0x39,
+ 0x38,
+ 0x38,
+ 0x37,
+ 0x37,
+ 0x37,
+ 0x36,
+ 0x36,
+ 0x35,
+ 0x35,
+ 0x34,
+ 0x34,
+ 0x33,
+ 0x33,
+ 0x33,
+ 0x32,
+ 0x32,
+ 0x31,
+ 0x31,
+ 0x31,
+ 0x30,
+ 0x30,
+ 0x2F,
+ 0x2F,
+ 0x2F,
+ 0x2E,
+ 0x2E,
+ 0x2D,
+ 0x2D,
+ 0x2D,
+ 0x2C,
+ 0x2C,
+ 0x2B,
+ 0x2B,
+ 0x2B,
+ 0x2A,
+ 0x2A,
+ 0x2A,
+ 0x29,
+ 0x29,
+ 0x29,
+ 0x28,
+ 0x28,
+ 0x27,
+ 0x27,
+ 0x27,
+ 0x26,
+ 0x26,
+ 0x26,
+ 0x25,
+ 0x25,
+ 0x25,
+ 0x24,
+ 0x24,
+ 0x24,
+ 0x23,
+ 0x23,
+ 0x23,
+ 0x23,
+ 0x22,
+ 0x22,
+ 0x22,
+ 0x21,
+ 0x21,
+ 0x21,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x20,
+ 0x1F,
+ 0x1F,
+ 0x1F,
+ 0x1E,
+ 0x1E,
+ 0x1E,
+ 0x1E,
+ 0x1D,
+ 0x1D,
+ 0x1D,
+ 0x1C,
+ 0x1C,
+ 0x1C,
+ 0x1C,
+ 0x1B,
+ 0x1B,
+ 0x1B,
+ 0x1B,
+ 0x1A,
+ 0x1A,
+ 0x1A,
+ 0x1A,
+ 0x19,
+ 0x19,
+ 0x19,
+ 0x19,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x18,
+ 0x17,
+ 0x17,
+ 0x17,
+ 0x17,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x16,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x15,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x14,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x13,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x10,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0F,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0E,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0D,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0C,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0B,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x0A,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x09,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x08,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x07,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x06,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x05,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x04,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x03,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x02,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 101,
+ 101,
+ 128,
+ 165,
+ 165,
+ 180,
+ 213,
+};
+const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48] = {
+
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 101,
+ 101,
+ 128,
+ 165,
+ 165,
+ 180,
+ 213,
+};
+
+const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48] = {
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1782,
+ -1761,
+ -1737,
+ -1679,
+ -1638,
+ -1613,
+ -1590,
+ -1568,
+ -1516,
+ -1459,
+ -1395,
+ -1289,
+ -671,
+ -409,
+ -401,
+};
+const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48] = {
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1787,
+ -1782,
+ -1761,
+ -1737,
+ -1679,
+ -1638,
+ -1613,
+ -1590,
+ -1568,
+ -1516,
+ -1459,
+ -1395,
+ -1289,
+ -671,
+ -409,
+ -401,
+};
+#if PERCEPTUAL_MODEL_SLGAIN_SHIFT == 4
+const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = {
+ 7,
+ 7,
+ 6,
+ 5,
+ 5,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+};
+#elif PERCEPTUAL_MODEL_SLGAIN_SHIFT == 8
+const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48] = {
+
+ 112,
+ 112,
+ 96,
+ 80,
+ 80,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+};
+#endif
+const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = {
+
+ 112,
+ 112,
+ 96,
+ 80,
+ 80,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+ 64,
+};
+const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48] = {
+ 0,
+ -1561,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -289,
+ -4,
+ -1234,
+ -2295,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -569,
+ -229,
+ -8,
+ -905,
+ -1705,
+ -2324,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -789,
+ -445,
+ -173,
+ -16,
+ -656,
+ -1271,
+ -1765,
+ -2172,
+ -2520,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -961,
+ -616,
+ -340,
+ -136,
+ -28,
+ -488,
+ -976,
+ -1382,
+ -1729,
+ -2032,
+ -2305,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1088,
+ -743,
+ -465,
+ -257,
+ -148,
+ -31,
+ -371,
+ -769,
+ -1114,
+ -1417,
+ -1689,
+ -2054,
+ -2483,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1198,
+ -852,
+ -574,
+ -364,
+ -209,
+ -148,
+ -42,
+ -300,
+ -635,
+ -936,
+ -1207,
+ -1572,
+ -2000,
+ -2376,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1293,
+ -948,
+ -669,
+ -458,
+ -301,
+ -183,
+ -145,
+ -56,
+ -258,
+ -547,
+ -816,
+ -1179,
+ -1606,
+ -1982,
+ -2311,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1375,
+ -1029,
+ -750,
+ -539,
+ -381,
+ -260,
+ -180,
+ -142,
+ -68,
+ -231,
+ -487,
+ -846,
+ -1272,
+ -1647,
+ -1976,
+ -2261,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1444,
+ -1099,
+ -820,
+ -608,
+ -449,
+ -328,
+ -233,
+ -194,
+ -138,
+ -77,
+ -213,
+ -555,
+ -978,
+ -1352,
+ -1681,
+ -1966,
+ -2268,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1501,
+ -1155,
+ -876,
+ -665,
+ -505,
+ -383,
+ -287,
+ -210,
+ -193,
+ -130,
+ -79,
+ -298,
+ -711,
+ -1083,
+ -1411,
+ -1696,
+ -1997,
+ -2288,
+ -2550,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1567,
+ -1221,
+ -942,
+ -730,
+ -570,
+ -448,
+ -351,
+ -272,
+ -206,
+ -189,
+ -151,
+ -72,
+ -349,
+ -713,
+ -1039,
+ -1324,
+ -1625,
+ -1915,
+ -2177,
+ -2448,
+ -2552,
+ -2552,
+ -2552,
+ -1650,
+ -1304,
+ -1025,
+ -813,
+ -653,
+ -530,
+ -432,
+ -352,
+ -285,
+ -227,
+ -177,
+ -163,
+ -69,
+ -297,
+ -613,
+ -895,
+ -1195,
+ -1485,
+ -1746,
+ -2017,
+ -2238,
+ -2401,
+ -2545,
+ -1727,
+ -1381,
+ -1102,
+ -890,
+ -730,
+ -607,
+ -509,
+ -428,
+ -360,
+ -301,
+ -249,
+ -180,
+ -153,
+ -72,
+ -257,
+ -527,
+ -824,
+ -1112,
+ -1373,
+ -1643,
+ -1865,
+ -2028,
+ -2171,
+ -1798,
+ -1452,
+ -1173,
+ -960,
+ -800,
+ -677,
+ -579,
+ -498,
+ -430,
+ -370,
+ -317,
+ -246,
+ -192,
+ -145,
+ -76,
+ -224,
+ -505,
+ -790,
+ -1050,
+ -1320,
+ -1540,
+ -1703,
+ -1847,
+ -1860,
+ -1514,
+ -1234,
+ -1022,
+ -862,
+ -738,
+ -640,
+ -559,
+ -490,
+ -430,
+ -377,
+ -306,
+ -224,
+ -197,
+ -136,
+ -81,
+ -242,
+ -515,
+ -771,
+ -1040,
+ -1260,
+ -1422,
+ -1566,
+ -1923,
+ -1577,
+ -1297,
+ -1085,
+ -925,
+ -801,
+ -703,
+ -621,
+ -553,
+ -492,
+ -439,
+ -367,
+ -284,
+ -213,
+ -198,
+ -144,
+ -83,
+ -235,
+ -479,
+ -744,
+ -963,
+ -1125,
+ -1268,
+ -1986,
+ -1640,
+ -1360,
+ -1148,
+ -988,
+ -864,
+ -766,
+ -684,
+ -615,
+ -555,
+ -501,
+ -429,
+ -345,
+ -273,
+ -211,
+ -204,
+ -146,
+ -89,
+ -216,
+ -465,
+ -680,
+ -841,
+ -984,
+ -2043,
+ -1697,
+ -1417,
+ -1205,
+ -1044,
+ -921,
+ -822,
+ -741,
+ -672,
+ -611,
+ -557,
+ -485,
+ -401,
+ -328,
+ -264,
+ -211,
+ -205,
+ -140,
+ -93,
+ -227,
+ -430,
+ -588,
+ -729,
+ -2104,
+ -1758,
+ -1479,
+ -1266,
+ -1106,
+ -982,
+ -884,
+ -802,
+ -733,
+ -673,
+ -619,
+ -546,
+ -461,
+ -388,
+ -324,
+ -269,
+ -212,
+ -211,
+ -151,
+ -100,
+ -195,
+ -336,
+ -472,
+ -2163,
+ -1817,
+ -1537,
+ -1324,
+ -1164,
+ -1040,
+ -942,
+ -860,
+ -791,
+ -731,
+ -676,
+ -604,
+ -519,
+ -445,
+ -380,
+ -325,
+ -268,
+ -226,
+ -219,
+ -147,
+ -114,
+ -167,
+ -280,
+ -2203,
+ -1857,
+ -1577,
+ -1365,
+ -1205,
+ -1081,
+ -982,
+ -901,
+ -831,
+ -771,
+ -717,
+ -644,
+ -559,
+ -485,
+ -420,
+ -364,
+ -306,
+ -252,
+ -239,
+ -206,
+ -132,
+ -122,
+ -163,
+ -2224,
+ -1878,
+ -1598,
+ -1386,
+ -1225,
+ -1102,
+ -1003,
+ -921,
+ -852,
+ -792,
+ -737,
+ -665,
+ -580,
+ -505,
+ -441,
+ -385,
+ -326,
+ -271,
+ -222,
+ -224,
+ -176,
+ -121,
+ -114,
+};
+const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = {
+ 0,
+ -1561,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -289,
+ -4,
+ -1234,
+ -2295,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -569,
+ -229,
+ -8,
+ -905,
+ -1705,
+ -2324,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -789,
+ -445,
+ -173,
+ -16,
+ -656,
+ -1271,
+ -1765,
+ -2172,
+ -2520,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -961,
+ -616,
+ -340,
+ -136,
+ -28,
+ -488,
+ -976,
+ -1382,
+ -1729,
+ -2032,
+ -2305,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1088,
+ -743,
+ -465,
+ -257,
+ -148,
+ -31,
+ -371,
+ -769,
+ -1114,
+ -1417,
+ -1689,
+ -2054,
+ -2483,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1198,
+ -852,
+ -574,
+ -364,
+ -209,
+ -148,
+ -42,
+ -300,
+ -635,
+ -936,
+ -1207,
+ -1572,
+ -2000,
+ -2376,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1293,
+ -948,
+ -669,
+ -458,
+ -301,
+ -183,
+ -145,
+ -56,
+ -258,
+ -547,
+ -816,
+ -1179,
+ -1606,
+ -1982,
+ -2311,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1375,
+ -1029,
+ -750,
+ -539,
+ -381,
+ -260,
+ -180,
+ -142,
+ -68,
+ -231,
+ -487,
+ -846,
+ -1272,
+ -1647,
+ -1976,
+ -2261,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1444,
+ -1099,
+ -820,
+ -608,
+ -449,
+ -328,
+ -233,
+ -194,
+ -138,
+ -77,
+ -213,
+ -555,
+ -978,
+ -1352,
+ -1681,
+ -1966,
+ -2268,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1501,
+ -1155,
+ -876,
+ -665,
+ -505,
+ -383,
+ -287,
+ -210,
+ -193,
+ -130,
+ -79,
+ -298,
+ -711,
+ -1083,
+ -1411,
+ -1696,
+ -1997,
+ -2288,
+ -2550,
+ -2552,
+ -2552,
+ -2552,
+ -2552,
+ -1567,
+ -1221,
+ -942,
+ -730,
+ -570,
+ -448,
+ -351,
+ -272,
+ -206,
+ -189,
+ -151,
+ -72,
+ -349,
+ -713,
+ -1039,
+ -1324,
+ -1625,
+ -1915,
+ -2177,
+ -2448,
+ -2552,
+ -2552,
+ -2552,
+ -1650,
+ -1304,
+ -1025,
+ -813,
+ -653,
+ -530,
+ -432,
+ -352,
+ -285,
+ -227,
+ -177,
+ -163,
+ -69,
+ -297,
+ -613,
+ -895,
+ -1195,
+ -1485,
+ -1746,
+ -2017,
+ -2238,
+ -2401,
+ -2545,
+ -1727,
+ -1381,
+ -1102,
+ -890,
+ -730,
+ -607,
+ -509,
+ -428,
+ -360,
+ -301,
+ -249,
+ -180,
+ -153,
+ -72,
+ -257,
+ -527,
+ -824,
+ -1112,
+ -1373,
+ -1643,
+ -1865,
+ -2028,
+ -2171,
+ -1798,
+ -1452,
+ -1173,
+ -960,
+ -800,
+ -677,
+ -579,
+ -498,
+ -430,
+ -370,
+ -317,
+ -246,
+ -192,
+ -145,
+ -76,
+ -224,
+ -505,
+ -790,
+ -1050,
+ -1320,
+ -1540,
+ -1703,
+ -1847,
+ -1860,
+ -1514,
+ -1234,
+ -1022,
+ -862,
+ -738,
+ -640,
+ -559,
+ -490,
+ -430,
+ -377,
+ -306,
+ -224,
+ -197,
+ -136,
+ -81,
+ -242,
+ -515,
+ -771,
+ -1040,
+ -1260,
+ -1422,
+ -1566,
+ -1923,
+ -1577,
+ -1297,
+ -1085,
+ -925,
+ -801,
+ -703,
+ -621,
+ -553,
+ -492,
+ -439,
+ -367,
+ -284,
+ -213,
+ -198,
+ -144,
+ -83,
+ -235,
+ -479,
+ -744,
+ -963,
+ -1125,
+ -1268,
+ -1986,
+ -1640,
+ -1360,
+ -1148,
+ -988,
+ -864,
+ -766,
+ -684,
+ -615,
+ -555,
+ -501,
+ -429,
+ -345,
+ -273,
+ -211,
+ -204,
+ -146,
+ -89,
+ -216,
+ -465,
+ -680,
+ -841,
+ -984,
+ -2043,
+ -1697,
+ -1417,
+ -1205,
+ -1044,
+ -921,
+ -822,
+ -741,
+ -672,
+ -611,
+ -557,
+ -485,
+ -401,
+ -328,
+ -264,
+ -211,
+ -205,
+ -140,
+ -93,
+ -227,
+ -430,
+ -588,
+ -729,
+ -2104,
+ -1758,
+ -1479,
+ -1266,
+ -1106,
+ -982,
+ -884,
+ -802,
+ -733,
+ -673,
+ -619,
+ -546,
+ -461,
+ -388,
+ -324,
+ -269,
+ -212,
+ -211,
+ -151,
+ -100,
+ -195,
+ -336,
+ -472,
+ -2163,
+ -1817,
+ -1537,
+ -1324,
+ -1164,
+ -1040,
+ -942,
+ -860,
+ -791,
+ -731,
+ -676,
+ -604,
+ -519,
+ -445,
+ -380,
+ -325,
+ -268,
+ -226,
+ -219,
+ -147,
+ -114,
+ -167,
+ -280,
+ -2203,
+ -1857,
+ -1577,
+ -1365,
+ -1205,
+ -1081,
+ -982,
+ -901,
+ -831,
+ -771,
+ -717,
+ -644,
+ -559,
+ -485,
+ -420,
+ -364,
+ -306,
+ -252,
+ -239,
+ -206,
+ -132,
+ -122,
+ -163,
+ -2224,
+ -1878,
+ -1598,
+ -1386,
+ -1225,
+ -1102,
+ -1003,
+ -921,
+ -852,
+ -792,
+ -737,
+ -665,
+ -580,
+ -505,
+ -441,
+ -385,
+ -326,
+ -271,
+ -222,
+ -224,
+ -176,
+ -121,
+ -114,
+};
+
+const Word32 c_pfMagLUT[8] = /* Q31 */
+{
+ 0, 394599072, 775760576, 1130504448, 1446750336, 1713728896, 1922348544, 2065504896
+};
+
+const Word32 c_pfP2RRealLUT[32] = /* Q31 */
+{
+ INT_MIN, -2106220416, -1984016384, -1785567488, -1518500224, -1193078272,
+ -821806592, -418953280, -94, 418953088, 821806400, 1193077888,
+ 1518500224, 1785567360, 1984016128, 2106220288, 2147483647, 2106220288,
+ 1984016128, 1785567360, 1518500224, 1193077888, 821806400, 418953088,
+ -94, -418953280, -821806592, -1193078272, -1518500224, -1785567488,
+ -1984016384, -2106220416
+};
+
+const Word32 c_pfP2RImagLUT[32] = /* Q31 */
+{
+ 188, -418953248, -821806080, -1193077888, -1518500224, -1785567232,
+ -1984016128, -2106220288, INT_MIN, -2106220416, -1984016128, -1785567488,
+ -1518500224, -1193078016, -821806464, -418953280, 0, 418953280,
+ 821806464, 1193078016, 1518500224, 1785567488, 1984016128, 2106220416,
+ 2147483647, 2106220288, 1984016128, 1785567232, 1518500224, 1193077888,
+ 821806080, 418953248
+};
+
+const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN] = /* Q31 */
+{
+ 190779840, 338280192, 610825408, 966922816, 1352359680, 1708457216, 1981002240, 2128502656, 2128502528, 1981002240, 1708456960, 1352359808, 966922624, 610825152, 338280192, 190779776
+};
+#endif
diff --git a/lib_isar/isar_lcld_rom_tables.h b/lib_isar/isar_lcld_rom_tables.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f1e80583dc61bb94fcd1d3e46a5322d2e2c89bb
--- /dev/null
+++ b/lib_isar/isar_lcld_rom_tables.h
@@ -0,0 +1,245 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef _ISAR_LCLD_ROM_TABLES_H_
+#define _ISAR_LCLD_ROM_TABLES_H_
+
+#include
+#include "options.h"
+#include "typedef.h"
+#ifndef M_PI
+
+#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI
+#define M_ONE_BY_PI_FX 10430 // 1/pi in Q15
+
+#endif
+
+#define LCLD_BLOCKS_PER_FRAME ( 16 )
+#define LCLD_MAX_BLOCKS_PER_FRAME ( 16 )
+#define LCLD_BANDS ( 60 )
+#define LCLD_PRED_WIN_LEN ( 16 )
+#define LCLD_MAX_NUM_PRED_SUBSETS ( 8 )
+#define MAX_BANDS ( 23 )
+#define MAX_BANDS_48 ( 23 )
+#define DEF_BANDS_48 ( 22 )
+
+#define ENV_MIN ( -64 )
+#define ENV_MAX ( 64 )
+
+#define ENV0_BITS ( 7 )
+
+#define ENV_DELTA_MIN ( -32 )
+#define ENV_DELTA_MIN_FX ( -1073741824 )
+#define ENV_DELTA_MAX ( 31 )
+#define ENV_DELTA_MAX_FX ( 1040187392 )
+
+#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 )
+
+#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 )
+
+#define MIN_ALLOC ( 0 )
+#define MAX_ALLOC ( 31 )
+
+#define ALLOC_OFFSET_SCALE ( 8 )
+
+#define ALLOC_OFFSET_BITS ( 8 )
+
+#define MIN_ALLOC_OFFSET ( -128 )
+#define MAX_ALLOC_OFFSET ( 127 )
+#define READ_LENGTH ( 4 )
+
+#define ALLOC_TABLE_SIZE ( 32 )
+
+#ifndef _PI_
+#define _PI_ ( 3.14159265358979f )
+#endif
+#define PRED_MAX_VAL ( 12 )
+#define PRED_MIN_VAL ( -PRED_MAX_VAL )
+#define PRED_QUANT_FACTOR ( (float) PRED_MAX_VAL )
+#define PRED_QUANT_FACTOR_FX ( PRED_MAX_VAL )
+#define PRED_BAND0_BITS ( 5 )
+
+#define PHASE_MAX_VAL ( 12 )
+#define PHASE_MIN_VAL ( -PHASE_MAX_VAL )
+#define PHASE_QUANT_FACTOR ( (float) PHASE_MAX_VAL / _PI_ )
+#define PHASE_QUANT_FACTOR_FX_Q29 ( 2050695826 )
+#define PHASE_DIFF_DIM ( 2 )
+#define PHASE_BAND0_BITS ( 5 )
+
+#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 )
+
+// #define USE_DEMOD_TABLES
+
+#define HUFF_DEC_TABLE_SIZE ( 16 )
+
+extern const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48];
+extern const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS];
+extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2];
+extern const Word32 c_afRotRealImag_fx[PRED_MAX_VAL - PRED_MIN_VAL + 1][2];
+extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48];
+extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48];
+
+extern const float c_afScaleFactor[ALLOC_TABLE_SIZE];
+extern const float c_afInvScaleFactor[ALLOC_TABLE_SIZE];
+extern const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE];
+extern const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE];
+extern const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE];
+extern const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE];
+extern const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE];
+extern const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE];
+extern const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE];
+extern const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE];
+extern const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE];
+extern const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE];
+extern const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE];
+
+
+#define LOG_ADD_TABLE_LENGTH ( 512 )
+
+extern const int32_t c_aiBandwidths48[MAX_BANDS_48];
+extern const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH];
+extern const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48];
+extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH];
+extern const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48];
+
+
+extern const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48];
+extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48];
+extern const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48];
+extern const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48];
+extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48];
+extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48];
+
+
+#define PRED_QUNAT_FILTER_MAG_BITS ( 3 )
+#define PRED_QUANT_FILTER_PHASE_BITS ( 5 )
+#define PRED_QUANT_FILTER_MAG_MIN ( 0 )
+#define PRED_QUANT_FILTER_MAG_MAX ( 7 )
+#define PRED_QUANT_FILTER_PHASE_MIN ( -16 )
+#define PRED_QUANT_FILTER_PHASE_MAX ( 15 )
+
+extern const uint16_t c_aauiLCLDHuffEnc1[16][2];
+extern const uint16_t c_aauiLCLDHuffEnc2[16][2];
+extern const uint16_t c_aauiLCLDHuffEnc3[25][2];
+extern const uint16_t c_aauiLCLDHuffEnc4[36][2];
+extern const uint16_t c_aauiLCLDHuffEnc5[36][2];
+extern const uint16_t c_aauiLCLDHuffEnc6[49][2];
+extern const uint16_t c_aauiLCLDHuffEnc7[64][2];
+extern const uint16_t c_aauiLCLDHuffEnc8[81][2];
+extern const uint16_t c_aauiLCLDHuffEnc9[100][2];
+extern const uint16_t c_aauiLCLDHuffEnc10[169][2];
+extern const uint16_t c_aauiLCLDHuffEnc11[196][2];
+extern const uint16_t c_aauiLCLDHuffEnc12[289][2];
+extern const uint16_t c_aauiLCLDHuffEnc13[324][2];
+extern const uint16_t c_aauiLCLDHuffEnc14[400][2];
+extern const uint16_t c_aauiLCLDHuffEnc15[576][2];
+extern const uint16_t c_aauiLCLDHuffEnc16[729][2];
+extern const uint16_t c_aauiLCLDHuffEnc17[729][2];
+extern const uint16_t c_aauiLCLDHuffEnc18[28][2];
+extern const uint16_t c_aauiLCLDHuffEnc19[29][2];
+extern const uint16_t c_aauiLCLDHuffEnc20[32][2];
+extern const uint16_t c_aauiLCLDHuffEnc21[37][2];
+extern const uint16_t c_aauiLCLDHuffEnc22[39][2];
+extern const uint16_t c_aauiLCLDHuffEnc23[46][2];
+extern const uint16_t c_aauiLCLDHuffEnc24[55][2];
+extern const uint16_t c_aauiLCLDHuffEnc25[65][2];
+extern const uint16_t c_aauiLCLDHuffEnc26[77][2];
+extern const uint16_t c_aauiLCLDHuffEnc27[91][2];
+extern const uint16_t c_aauiLCLDHuffEnc28[109][2];
+extern const uint16_t c_aauiLCLDHuffEnc29[129][2];
+extern const uint16_t c_aauiLCLDHuffEnc30[153][2];
+extern const uint16_t c_aauiLCLDHuffEnc31[181][2];
+extern const uint16_t c_aauiLCLDHuffEnc33[16][2];
+extern const uint16_t c_aauiLCLDHuffEnc34[16][2];
+extern const uint16_t c_aauiLCLDHuffEnc35[25][2];
+extern const uint16_t c_aauiLCLDHuffEnc36[36][2];
+extern const uint16_t c_aauiLCLDHuffEnc37[36][2];
+extern const uint16_t c_aauiLCLDHuffEnc38[49][2];
+extern const uint16_t c_aauiLCLDHuffEnc39[64][2];
+extern const uint16_t c_aauiLCLDHuffEnc40[81][2];
+extern const uint16_t c_aauiLCLDHuffEnc41[100][2];
+extern const uint16_t c_aauiLCLDHuffEnc42[169][2];
+extern const uint16_t c_aauiLCLDHuffEnc43[196][2];
+extern const uint16_t c_aauiLCLDHuffEnc44[289][2];
+extern const uint16_t c_aauiLCLDHuffEnc45[324][2];
+extern const uint16_t c_aauiLCLDHuffEnc46[400][2];
+extern const uint16_t c_aauiLCLDHuffEnc47[576][2];
+extern const uint16_t c_aauiLCLDHuffEnc48[729][2];
+extern const uint16_t c_aauiLCLDHuffEnc49[729][2];
+extern const uint16_t c_aauiLCLDHuffEnc50[28][2];
+extern const uint16_t c_aauiLCLDHuffEnc51[29][2];
+extern const uint16_t c_aauiLCLDHuffEnc52[32][2];
+extern const uint16_t c_aauiLCLDHuffEnc53[37][2];
+extern const uint16_t c_aauiLCLDHuffEnc54[39][2];
+extern const uint16_t c_aauiLCLDHuffEnc55[46][2];
+extern const uint16_t c_aauiLCLDHuffEnc56[55][2];
+extern const uint16_t c_aauiLCLDHuffEnc57[65][2];
+extern const uint16_t c_aauiLCLDHuffEnc58[77][2];
+extern const uint16_t c_aauiLCLDHuffEnc59[91][2];
+extern const uint16_t c_aauiLCLDHuffEnc60[109][2];
+extern const uint16_t c_aauiLCLDHuffEnc61[129][2];
+extern const uint16_t c_aauiLCLDHuffEnc62[153][2];
+extern const uint16_t c_aauiLCLDHuffEnc63[181][2];
+extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2];
+extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE];
+
+#ifdef USE_DEMOD_TABLES
+extern const int32_t c_aaiHuffDemod1[16][2];
+extern const int32_t c_aaiHuffDemod2[16][2];
+extern const int32_t c_aaiHuffDemod3[25][2];
+extern const int32_t c_aaiHuffDemod4[36][2];
+extern const int32_t c_aaiHuffDemod5[36][2];
+extern const int32_t c_aaiHuffDemod6[49][2];
+extern const int32_t c_aaiHuffDemod7[64][2];
+extern const int32_t c_aaiHuffDemod8[81][2];
+extern const int32_t c_aaiHuffDemod9[100][2];
+extern const int32_t c_aaiHuffDemod10[169][2];
+extern const int32_t c_aaiHuffDemod11[196][2];
+extern const int32_t c_aaiHuffDemod12[289][2];
+extern const int32_t c_aaiHuffDemod13[324][2];
+extern const int32_t c_aaiHuffDemod14[400][2];
+extern const int32_t c_aaiHuffDemod15[576][2];
+extern const int32_t c_aaiHuffDemod16[729][2];
+extern const int32_t c_aaiHuffDemod17[729][2];
+extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2];
+#endif
+
+extern const uint32_t c_aaiRMSEnvHuffEnc[64][2];
+extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE];
+
+extern const Word32 c_pfMagLUT[8]; /* Q31 */
+extern const Word32 c_pfP2RRealLUT[32]; /* Q31 */
+extern const Word32 c_pfP2RImagLUT[32]; /* Q31 */
+extern const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN]; /* Q31 */
+
+
+#endif /* _TABLES_H_ */
diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h
new file mode 100644
index 0000000000000000000000000000000000000000..24f93b2831f4c6e1df0c5e980140b12c5004d7aa
--- /dev/null
+++ b/lib_isar/isar_prot.h
@@ -0,0 +1,465 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_PROT_H
+#define ISAR_PROT_H
+
+
+#include "isar_stat.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+
+#include
+#include "options.h"
+#include "ivas_error.h"
+#include "lib_isar_post_rend.h"
+#include "enh64.h"
+
+Word32 ISAR_SPLIT_REND_BITStream_read_int32(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 bits );
+
+void ISAR_SPLIT_REND_BITStream_write_int32(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 val,
+ const Word32 bits );
+
+ivas_error isar_splitBinLCLDEncOpen(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
+ const int32_t iSampleRate,
+ const int16_t iChannels,
+ const int32_t iDataRate,
+ const int16_t iNumBlocks,
+ const int16_t iNumIterations );
+
+ivas_error isar_splitBinRendPLCOpen(
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC,
+ int16_t iNumSubSets );
+
+void isar_splitBinRendPLCClose(
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC );
+ivas_error isar_splitBinLCLDDecOpen(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
+ const Word32 iSampleRate,
+ const Word16 iChannels,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations );
+void isar_splitBinLCLDDecClose(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec );
+
+void isar_splitBinRendPLCsaveState(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const int16_t num_chs,
+ const int16_t iNumBlocks,
+ const int16_t iNumIterations );
+
+void isar_splitBinRendPLC_xf_fx(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 num_chs,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations,
+ Word32 **ppiDecodingFailed,
+ Word32 **ppiDecodingFailedPrev,
+ Word16 exp );
+
+void isar_splitBinRendPLC(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 num_chs,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations,
+ Word32 **ppiDecodingFailed,
+ Word16 exp );
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+void isar_log_cldfb2wav_data(
+ float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ HANDLE_CLDFB_FILTER_BANK *cldfbSyn,
+ const int16_t num_chs,
+ const int16_t num_freq_bands,
+ const int32_t output_Fs,
+ const int16_t start_slot_idx,
+ const int16_t md_band_idx,
+ const char *filename );
+#endif
+
+void isar_SplitRenderer_PostRenderer(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
+ Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
+ const IVAS_QUATERNION Quaternion_act );
+
+void isar_splitBinLCLDDecProcess(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 *Q_cldfb_final,
+ const Word16 bfi );
+
+void set_fix_rotation_mat_fx(
+ Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+void set_fix_rotation_mat(
+ float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+
+void isar_splitBinLCLDEncClose(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc );
+void isar_splitBinLCLDEncProcess(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
+ Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word32 available_bits,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word16 *q_final );
+
+void set_pose_types_fx(
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+void set_pose_types(
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+
+void isar_split_rend_init_huff_cfg(
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg );
+
+ivas_error isar_splitBinPostRendOpen(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const int32_t output_Fs );
+
+void isar_splitBinPostRendClose(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend );
+
+void isar_SplitRenderer_getdiagdiff(
+ Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ const Word16 sign,
+ const Word16 min_val,
+ const Word16 max_val );
+
+void isar_renderSplitGetMultiBinPoseData_fx(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis );
+void isar_renderSplitGetMultiBinPoseData(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis );
+
+void isar_split_rend_get_quant_params_fx(
+ const Word16 num_md_bands,
+ Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ const Word16 ro_flag,
+#endif
+ Word16 *num_quant_strats
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ ,
+ Word16 *num_complex_bands
+#endif
+);
+
+void isar_split_rend_get_quant_params(
+ const int16_t num_md_bands,
+ int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ int16_t *num_quant_strats,
+ int16_t *num_complex_bands );
+
+void isar_splitBinPostRendMdDec_fx(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ,
+ BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend
+#endif
+);
+
+void Quat2EulerDegree(
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ float *yaw, /* o : yaw */
+ float *pitch, /* o : pitch */
+ float *roll /* o : roll */
+);
+
+void ivas_mat_mult_2by2_complex(
+ float in_re1[2][2],
+ float in_im1[2][2],
+ float in_re2[2][2],
+ float in_im2[2][2],
+ float out_re2[2][2],
+ float out_im2[2][2] );
+
+void isar_mat_mult_2by2_complex_fx(
+ Word32 in_re1_fx[2][2],
+ Word16 exp_re1,
+ Word32 in_im1_fx[2][2],
+ Word16 exp_im1,
+ Word32 in_re2_fx[2][2],
+ Word16 exp_re2,
+ Word32 in_im2_fx[2][2],
+ Word16 exp_im2,
+ Word32 out_re2_fx[2][2],
+ Word16 *final_exp_re_1,
+ Word32 out_im2_fx[2][2],
+ Word16 *final_exp_im_1 );
+
+void isar_rend_CldfbSplitPostRendProcess(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const IVAS_QUATERNION QuaternionPost,
+ Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ Word16 Q_cldfb_in,
+ Word32 output_fx[][L_FRAME48k],
+ Word16 *Q_out,
+ const Word16 cldfb_in_flag );
+
+void isar_init_multi_bin_pose_data_fx(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+
+/* Copy for encoder, to be removed */
+void isar_init_multi_bin_pose_data_fx_enc(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+void isar_init_multi_bin_pose_data(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+
+void isar_rend_CldfbSplitPreRendProcess(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ const IVAS_QUATERNION headPosition,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_re,
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_im,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 target_md_bits,
+ const Word16 low_res_pre_rend_rot,
+ const Word16 ro_md_flag );
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+Word16 isar_renderSplitGetRot_axisNumBits(
+ const Word16 dof );
+
+ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
+ const Word16 dof,
+ const Word16 code );
+
+Word16 isar_renderSplitGetCodeFromRot_axis(
+ const Word16 dof,
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
+ Word16 *num_bits );
+#endif
+
+void isar_init_split_post_rend_handles(
+ ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper );
+
+ivas_error isar_splitBinPreRendOpen(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const int32_t output_Fs
+#else
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+#endif
+);
+
+void isar_splitBinPreRendClose(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend );
+
+void isar_set_split_rend_ht_setup_fx(
+ SPLIT_REND_WRAPPER *hSplitrend,
+ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
+ Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] );
+
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+Word32 isar_get_lc3plus_bitrate(
+ const Word32 SplitRendBitRate,
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
+ const Word16 split_prerender_frame_size_ms );
+#endif
+
+ivas_error isar_split_rend_validate_config(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
+ const Word16 is_pcm_out );
+
+Word32 isar_get_lcld_bitrate(
+ const Word32 SplitRendBitRate,
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode );
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+Word8 isar_get_lc3plus_bitrate_id(
+ const Word32 SplitRendBitRate );
+#endif
+
+ivas_error splitRendLc3plusEncodeAndWrite(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const int32_t available_bits,
+#else
+ const int32_t SplitRendBitRate,
+#endif
+ Word32 *in[],
+ Word16 Q_sig );
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ivas_error isar_framesize_to_ms(
+ const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
+ Word16 *ms /* o : frame size in ms */
+);
+#endif
+Word32 isar_get_split_rend_md_target_brate(
+ const Word32 SplitRendBitRate,
+ const Word16 pcm_out_flag );
+
+ivas_error isar_split_rend_choose_default_codec(
+ ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ Word16 *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */
+#endif
+ Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */
+ const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */
+ const Word16 pcm_out_flag, /* i : flag to indicate PCM output */
+ const Word16 num_subframes /* i : number of subframes */
+);
+
+void ISAR_SPLIT_REND_BITStream_init(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 buf_len_bytes,
+ UWord8 *pbuf );
+
+void isar_split_rend_huffman_dec_init_min_max_len(
+ isar_split_rend_huffman_cfg_t *p_huff_cfg );
+
+Word16 wrap_a(
+ Word16 val,
+ const Word16 min_val,
+ const Word16 max_val );
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+Word32 isar_get_lc3plus_size_from_id(
+ const Word8 SplitRendBitRateId,
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
+ const Word16 split_prerender_frame_size_ms );
+#endif
+
+void isar_renderSplitUpdateNoCorrectionPoseData(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+
+Word32 get_bit(
+ const Word32 state,
+ const Word32 bit_id );
+
+ivas_error split_renderer_open_lc3plus(
+ SPLIT_REND_WRAPPER *hSplitRendWrapper,
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
+ const Word32 OutSampleRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const IVAS_RENDER_FRAMESIZE ivas_frame_size
+#else
+ const int16_t num_subframes
+#endif
+);
+
+ISAR_POST_REND_AudioConfigType isar_getAudioConfigType(
+ const IVAS_AUDIO_CONFIG config );
+
+void isar_init_split_rend_handles(
+ SPLIT_REND_WRAPPER *hSplitRendWrapper );
+
+ivas_error isar_renderMultiTDBinToSplitBinaural(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ const IVAS_QUATERNION headPosition,
+ const Word32 SplitRendBitRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const Word16 isar_frame_size_ms,
+#endif
+ const Word16 codec_frame_size_ms,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word16 max_bands,
+ // float *in[],
+ Word32 *in_fx[], // Q11
+ Word16 Q_sig,
+ const Word16 low_res_pre_rend_rot,
+ const Word16 pcm_out_flag,
+ const Word16 ro_md_flag );
+
+void lc3plusTimeAlignCldfbPoseCorr( SPLIT_REND_WRAPPER *hSplitBin,
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 *Q_in );
+
+#endif
+void set16_fx(
+ Word16 y[], /* i/o: Vector to set */
+ const Word16 a, /* i : Value to set the vector to */
+ const Word16 N /* i : Lenght of the vector */
+);
+
+void set32_fx(
+ Word32 y[], /* i/o: Vector to set */
+ const Word32 a, /* i : Value to set the vector to */
+ const Word16 N /* i : Lenght of the vector */
+);
+
+Word16 ceil_log_2(
+ UWord64 val );
+/* clang-format on */
+
+#endif /* IVAS_PROT_REND_H */
diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c
new file mode 100644
index 0000000000000000000000000000000000000000..13a786b167984ccae711b2817e367c195ec4c07a
--- /dev/null
+++ b/lib_isar/isar_rom_post_rend.c
@@ -0,0 +1,196 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "cnst.h"
+#include "isar_cnst.h"
+#include
+#include "wmc_auto.h"
+
+/* clang-format off */
+
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*----------------------------------------------------------------------*
+ * Binuaral split rendering ROM tables
+ *-----------------------------------------------------------------------*/
+
+/* rotations in this array are relative to ref rotation */
+const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */
+const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */
+const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */
+const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f};
+const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f};
+const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f};
+const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f};
+
+const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */
+const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */
+const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */
+const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f};
+const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f};
+const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f};
+const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f};
+
+/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */
+const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4] = { ONE_IN_Q31, 2074309917, 1984016189, 1859775393 }; /* Q31 */
+
+const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60
+};
+
+const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
+{
+ {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12},
+ {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61},
+ {12,7,125},{13,8,254},{14,8,255}
+};
+
+const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
+{
+ { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 },
+ { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 },
+ { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 },
+ { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 }
+};
+
+const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] =
+{
+ { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 },
+ { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 },
+ { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 },
+ { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 }
+};
+
+const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] =
+{
+ {-31,11,2040},
+ {-30,11,2041},
+ {-29,11,2042},
+ {-28,11,2043},
+ {-27,10,1012},
+ {-26,10,1013},
+ {-25,10,1014},
+ {-24,10,1015},
+ {-23,9,498},
+ {-22,9,499},
+ {-21,9,500},
+ {-20,9,501},
+ {-19,8,242},
+ {-18,8,243},
+ {-17,8,244},
+ {-16,8,245},
+ {-15,7,112},
+ {-14,7,113},
+ {-13,7,114},
+ {-12,7,115},
+ {-11,6,48},
+ {-10,6,49},
+ {-9,6,50},
+ {-8,6,51},
+ {-7,5,16},
+ {-6,5,17},
+ {-5,5,18},
+ {-4,5,19},
+ {-3,4,2},
+ {-2,4,3},
+ {-1,4,4},
+ {0,3,0},
+ {1,4,5},
+ {2,4,6},
+ {3,4,7},
+ {4,5,20},
+ {5,5,21},
+ {6,5,22},
+ {7,5,23},
+ {8,6,52},
+ {9,6,53},
+ {10,6,54},
+ {11,6,55},
+ {12,7,116},
+ {13,7,117},
+ {14,7,118},
+ {15,7,119},
+ {16,7,120},
+ {17,8,246},
+ {18,8,247},
+ {19,8,248},
+ {20,9,502},
+ {21,9,503},
+ {22,9,504},
+ {23,9,505},
+ {24,10,1016},
+ {25,10,1017},
+ {26,10,1018},
+ {27,10,1019},
+ {28,11,2044},
+ {29,11,2045},
+ {30,11,2046},
+ {31,11,2047},
+};
+
+const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] =
+{
+ {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507},
+ {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121},
+ {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8},
+ {-2,4,9},{-1,3,2},{0,2,0},{1,3,3},
+ {2,4,10},{3,4,11},{4,5,26},{5,5,27},
+ {6,6,58},{7,6,59},{8,7,122},{9,7,123},
+ {10,7,124},{11,8,252},{12,9,508},{13,9,509},
+ {14,10,1022},{15,10,1023},
+};
+
+const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] =
+{
+ {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507},
+ {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121},
+ {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8},
+ {-2,4,9},{-1,3,2},{0,2,0},{1,3,3},
+ {2,4,10},{3,4,11},{4,5,26},{5,5,27},
+ {6,6,58},{7,6,59},{8,7,122},{9,7,123},
+ {10,7,124},{11,8,252},{12,9,508},{13,9,509},
+{14,10,1022},{15,10,1023},
+};
+
+#endif
+
+/* Tables for split renderer fixed converison */
+const Word16 fade_table_fx[4] =
+{ 8192, 16384, 24576, 32767 };
+
+/* clang-format on */
diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h
new file mode 100644
index 0000000000000000000000000000000000000000..2bfac9140c8d96fba47b06a6b35bbad1b1e65ae1
--- /dev/null
+++ b/lib_isar/isar_rom_post_rend.h
@@ -0,0 +1,82 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_ROM_POST_REND_H
+#define ISAR_ROM_POST_REND_H
+
+#include
+#include "options.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "cnst.h"
+#include "isar_cnst.h"
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+/*----------------------------------------------------------------------*
+ * Binuaral split rendering ROM tables
+ *-----------------------------------------------------------------------*/
+
+extern const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES];
+extern const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES];
+extern const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES];
+extern const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES];
+
+extern const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES];
+extern const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES];
+extern const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+extern const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES];
+
+/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */
+extern const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4]; /* Q31 */
+
+extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3];
+extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1];
+extern const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
+extern const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3];
+extern const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3];
+extern const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3];
+extern const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
+extern const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3];
+extern const int32_t split_rend_brate_tbl[];
+#endif
+
+/* Tables for fixed point conversion */
+extern const Word16 fade_table_fx[4];
+
+#endif
diff --git a/lib_isar/isar_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e5c3e2bb01f5a47d700077788eebf7c4d98f210
--- /dev/null
+++ b/lib_isar/isar_splitRend_lcld_dec.c
@@ -0,0 +1,284 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_prot.h"
+#include "ivas_prot.h"
+#include "prot.h"
+#include "control.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDDecOpen()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error isar_splitBinLCLDDecOpen(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
+ const Word32 iSampleRate,
+ const Word16 iChannels,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations )
+{
+ int16_t n;
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec;
+ ivas_error error;
+
+ IF( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+
+ splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */
+
+ splitBinLCLDDec->iChannels = iChannels;
+
+ IF( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+
+ FOR( n = 0; n < splitBinLCLDDec->iChannels; n++ )
+ {
+ IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) );
+ }
+ }
+#ifdef CLDFB_DEBUG
+ splitBinLCLDDec->numFrame = 0;
+ char cldfbFilename[50] = "cldfb_out.bin";
+ if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL )
+ {
+ fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename );
+ exit( -1 );
+ }
+ int16_t num_bands = CLDFB_NO_CHANNELS_MAX;
+ fwrite( &iChannels, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut );
+ fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut );
+#endif
+
+ IF( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ splitBinLCLDDec->iNumBlocks = iNumBlocks;
+ splitBinLCLDDec->iNumIterations = iNumIterations;
+
+ *hSplitBinLCLDDec = splitBinLCLDDec;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDDecClose()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinLCLDDecClose(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec )
+{
+ Word16 n;
+
+ IF( ( *hSplitBinLCLDDec ) != NULL )
+ {
+ IF( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL )
+ {
+ DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder );
+ }
+
+ FOR( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ )
+ {
+ free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx[n] );
+ free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx[n] );
+ }
+ free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx );
+ free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx );
+
+#ifdef CLDFB_DEBUG
+ if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL )
+ {
+ fclose( ( *hSplitBinLCLDDec )->cldfbOut );
+ }
+#endif
+ isar_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC );
+
+ free( *hSplitBinLCLDDec );
+ *hSplitBinLCLDDec = NULL;
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDDecProcess()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void isar_splitBinLCLDDecProcess(
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 *Q_cldfb_final,
+ const Word16 bfi )
+{
+ Word16 k, n;
+ Word16 itr;
+ *Q_cldfb_final = 11;
+ push_wmops( "isar_splitBinLCLDDecProcess" );
+
+ assert( hSplitBinLCLDDec != NULL );
+ assert( Cldfb_Out_Real_fx != NULL );
+ assert( Cldfb_Out_Imag_fx != NULL );
+ assert( pBits != NULL );
+#ifdef CLDFB_DEBUG
+ printf( "Bytes read = %d\n", iBytesWritten );
+#endif
+ IF( !bfi )
+ {
+ FOR( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ )
+ {
+ /* Initialized with zeros....... */
+ FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ )
+ {
+ FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ )
+ {
+ hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k] = Cldfb_Out_Real_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k];
+ hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k] = Cldfb_Out_Imag_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k];
+ set_l( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX );
+ set_l( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+
+ Word16 Q_in = 14;
+ DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal_fx, hSplitBinLCLDDec->pppfDecLCLDImag_fx, Q_in, Q_cldfb_final );
+
+#ifdef CLDFB_DEBUG
+ printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame );
+ int16_t writeByte = 0;
+ for ( k = 0; k < CLDFB_NO_COL_MAX; k++ )
+ {
+ for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ )
+ {
+ for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ )
+ {
+ writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut );
+ if ( writeByte != 1 )
+ exit( -1 );
+ writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut );
+ if ( writeByte != 1 )
+ exit( -1 );
+ }
+ }
+ }
+#endif
+ IF( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) )
+ {
+ IF( NE_16( *Q_cldfb_final, 11 ) )
+ {
+ FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ )
+ {
+ FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ )
+ {
+ FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11
+ hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11
+ }
+ }
+ }
+ *Q_cldfb_final = 11;
+ }
+ /* continue concealing */
+ isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final );
+ }
+ IF( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) )
+ {
+ IF( NE_16( *Q_cldfb_final, 11 ) )
+ {
+ FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ )
+ {
+ FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ )
+ {
+ FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
+ {
+ hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11
+ hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11
+ }
+ }
+ }
+ *Q_cldfb_final = 11;
+ }
+ /* cross-fade recovered frame into good frame */
+ isar_splitBinRendPLC_xf_fx( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final );
+ }
+ }
+ }
+ ELSE
+ {
+ /* set states in decoder */
+ SetDecodingUnresolved( hSplitBinLCLDDec->psLCLDDecoder );
+
+ /* do PLC for lost split renderer frame */
+ isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final );
+ }
+
+ /* save PLC state */
+ isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations );
+ hSplitBinLCLDDec->hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx = *Q_cldfb_final;
+ move16();
+ pop_wmops();
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c
new file mode 100644
index 0000000000000000000000000000000000000000..0f442a2f2b970565d5b385f2687674fb405a70a1
--- /dev/null
+++ b/lib_isar/isar_splitRend_lcld_enc.c
@@ -0,0 +1,239 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_prot.h"
+#include "ivas_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDEncOpen()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error isar_splitBinLCLDEncOpen(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
+ const Word32 iSampleRate,
+ const Word16 iChannels,
+ const Word32 iDataRate,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations )
+{
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc;
+ ivas_error error;
+
+ IF( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/
+
+ splitBinLCLDEnc->iChannels = iChannels;
+ IF( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (Word16) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( ( splitBinLCLDEnc->pppfLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( splitBinLCLDEnc->pppfLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+
+ FOR( Word16 n = 0; n < splitBinLCLDEnc->iChannels; n++ )
+ {
+ IF( ( splitBinLCLDEnc->pppfLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ IF( ( splitBinLCLDEnc->pppfLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
+ }
+ }
+
+ splitBinLCLDEnc->iNumIterations = iNumIterations;
+ splitBinLCLDEnc->iNumBlocks = iNumBlocks;
+
+#ifdef CLDFB_DEBUG
+ splitBinLCLDEnc->numFrame = 0;
+ char cldfbFilename[50] = "cldfb_in_ref.qmf";
+ if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL )
+ {
+ fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename );
+ exit( -1 );
+ }
+ int16_t chan, band;
+ fread( &chan, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn );
+ fread( &band, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn );
+#endif
+
+ *hSplitBinLCLDEnc = splitBinLCLDEnc;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDEncClose()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinLCLDEncClose(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc )
+{
+ IF( ( *hSplitBinLCLDEnc ) != NULL )
+ {
+ DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder );
+
+ FOR( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ )
+ {
+ free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx[n] );
+ free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx[n] );
+ }
+ free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx );
+ free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx );
+#ifdef CLDFB_DEBUG
+ if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL )
+ {
+ fclose( ( *hSplitBinLCLDEnc )->cldfbIn );
+ }
+#endif
+
+ free( *hSplitBinLCLDEnc );
+ *hSplitBinLCLDEnc = NULL;
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinLCLDEncProcess()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void isar_splitBinLCLDEncProcess(
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
+ Word32 Cldfb_In_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_In_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word32 available_bits,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word16 *q_final )
+{
+ Word32 iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local;
+ push_wmops( "isar_splitBinLCLDEncProcess" );
+ assert( hSplitBinLCLDEnc != NULL );
+ assert( Cldfb_In_Real_fx != NULL );
+ assert( Cldfb_In_Imag_fx != NULL );
+ assert( pBits != NULL );
+
+ available_bits_local = available_bits;
+ move32();
+ Word16 tmp, tmp_e;
+ /* A conversion is needed for the 3d pointer interface here ........ */
+ FOR( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ )
+ {
+
+ rem_itr = L_sub( hSplitBinLCLDEnc->iNumIterations, itr );
+ tmp = BASOP_Util_Divide3232_Scale( available_bits_local, rem_itr, &tmp_e );
+ available_bits_itr = shr( tmp, sub( 15, tmp_e ) ); // Q0
+ // available_bits_itr = available_bits_local / rem_itr;
+ FOR( Word32 n = 0; n < hSplitBinLCLDEnc->iChannels; n++ )
+ {
+ FOR( Word32 k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ )
+ {
+ hSplitBinLCLDEnc->pppfLCLDReal_fx[n][k] = Cldfb_In_Real_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k];
+ hSplitBinLCLDEnc->pppfLCLDImag_fx[n][k] = Cldfb_In_Imag_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k];
+ }
+ }
+#ifdef CLDFB_DEBUG
+ int16_t readByte = 0;
+ for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ )
+ {
+ for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ )
+ {
+ for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ )
+ {
+ readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn );
+ if ( readByte != 1 )
+ break;
+ readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn );
+ }
+ }
+ }
+
+ if ( readByte == 1 )
+ {
+ printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame );
+ }
+ else
+ {
+ printf( "Writing zeroes...\n" );
+ for ( int16_T k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ )
+ {
+ for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ )
+ {
+ for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ )
+ {
+ hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f;
+ hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f;
+ }
+ }
+ }
+ }
+#endif
+ EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal_fx, hSplitBinLCLDEnc->pppfLCLDImag_fx, &iBitsWritten, available_bits_itr, pBits, q_final );
+
+ available_bits_local = L_sub( available_bits_local, iBitsWritten );
+#ifdef DEBUGGING
+ assert( available_bits_local >= 0 );
+#endif
+
+#ifdef CLDFB_DEBUG
+ printf( "Bits written = %d\n", iBitsWritten );
+#endif
+ }
+ pop_wmops();
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c
new file mode 100644
index 0000000000000000000000000000000000000000..152fe52f3bcc531e4a0645f808465cb9f0f2ad2c
--- /dev/null
+++ b/lib_isar/isar_splitRendererPLC.c
@@ -0,0 +1,1316 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "ivas_prot.h"
+#include "prot.h"
+#include "isar_cnst.h"
+#include "isar_prot.h"
+#include "enh64.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+#include "prot_fx2.h"
+#include "basop_util.h"
+#include "basop_mpy.h"
+#include "enh64.h"
+
+/*-------------------------------------------------------------------------
+ * Local constants
+ *------------------------------------------------------------------------*/
+#define PI_CONST ( 341782638 ) // Q31
+#define DO_PERTURB 1
+#define PH_PERT_ONLY 1
+#define START_VAL_AVG_LEN 2
+#define SR_PLC_FADE_START 10 /* start fading at this number of bad frames in row */
+#define SR_PLC_MUTE 30 /* Total mute at this number of bad frames in row */
+#define SR_PLC_FADE_DEGREE -3 /* fading degree per frame in dB */
+#define SRHO_THRESH ( 2.f / 3.f * 0.1f )
+#define SRHO_THRESH_FX ( 143165584 )
+#define STH_THRESH_FX ( 749613227 )
+#define STH_THRESH ( 2.f / 3.f * PI2 / 12 )
+#define PLC_FADE_CNST SR_PLC_FADE_START *CLDFB_NO_COL_MAX
+#define PLC_MUTE_CNST SR_PLC_MUTE *CLDFB_NO_COL_MAX
+Word32 xf_alp_tab[CLDFB_PLC_XF] = { 1431655680, 715827840 };
+static Word16 find_guarded_bits_fx( Word32 n )
+{
+ return n <= 1 ? 0 : n <= 2 ? 1
+ : n <= 4 ? 2
+ : n <= 8 ? 3
+ : n <= 16 ? 4
+ : n <= 32 ? 5
+ : n <= 64 ? 6
+ : n <= 128 ? 7
+ : n <= 256 ? 8
+ : n <= 512 ? 9
+ : n <= 1024 ? 10
+ : n <= 2048 ? 11
+ : n <= 4096 ? 12
+ : n <= 8192 ? 13
+ : n <= 16384 ? 14
+ : 15;
+}
+
+/*-------------------------------------------------------------------------
+ * Function adaptive_polar_ext_plc()
+ *
+ *
+ *------------------------------------------------------------------------*/
+static void adaptive_polar_ext_plc_fx(
+ const Word32 *prev_real_fx,
+ const Word32 *prev_imag_fx,
+ Word32 *rec_real_fx,
+ Word32 *rec_imag_fx,
+ Word16 *rec_real_exp,
+ Word16 *rec_imag_exp
+#if CLDFB_PLC_XF > 0
+ ,
+ Word32 xf_alp_fx[CLDFB_PLC_XF],
+ Word32 xf_bet_fx[CLDFB_PLC_XF]
+#endif
+ ,
+ Word16 exp,
+ const Word16 iNumCols )
+
+{
+ /*TODO: Add basops and instrumentation where ever possible*/
+ Word32 uth_fx[CLDFB_NO_COL_MAX], urh_fx[CLDFB_NO_COL_MAX];
+ Word64 uthu_fx[CLDFB_NO_COL_MAX], drho_fx, srho_fx, diff_fx, dth_fx, sth_fx, ph_adj_fx, rat_real_fx, rat_imag_fx;
+ Word32 ph_diff_fx, ph_adj_t_fx, quot_fx, dth32, fac_real_fx, fac_imag_fx, rat_real32_fx, rat_imag32_fx, abs2inv_fx;
+ Word16 srho_q, sth_q, dth16, drho_q, rat_real_q, rat_imag_q, temp_16, rat_real_sum_q, rat_imag_sum_q, start_q, fac_real_q, fac_imag_q;
+ Word64 Ruu_real_fx[2], Ruu_imag_fx[2], abs_fac_fx;
+ Word32 Ruu_real_fx_1, Ruu_imag_fx_1, Ruu_real_fx_0, abs_fac_32, abs_fac_powj_32, comp_fac_fx;
+ Word16 Ruu_real_fx_1_q, Ruu_imag_fx_1_q, Ruu_real_fx_0_q, dth_q, urh_exp[CLDFB_NO_COL_MAX];
+ Word32 fac_ph_real_fx, fac_ph_imag_fx, abs_temp_fx;
+ Word32 start_real_fx, start_imag_fx, fac_powj_real_fx, fac_powj_imag_fx, temp_fx;
+ Word32 k, j;
+ Word16 quot_exp[CLDFB_NO_COL_MAX];
+ Word16 drho_exp[CLDFB_NO_COL_MAX];
+ Word16 srho_exp[CLDFB_NO_COL_MAX];
+ /* Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];
+ Word16 rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];*/
+ /* reset of accumulators */
+ ph_adj_fx = 0;
+ drho_fx = 0;
+ srho_fx = 0;
+ dth_fx = 0;
+ sth_fx = 0;
+ Word16 sqrt_exp = 0, sqrt_exp1;
+ Word32 temp_32;
+ Word16 lshift;
+ Word64 temp_64, real_sum, imag_sum;
+ /* calculate per-sample phase and magnitude evolution in preceding frame */
+ FOR( k = 0; k < iNumCols; k++ )
+ {
+ real_sum = W_mult_32_32( prev_real_fx[k], prev_real_fx[k] );
+ rat_real_sum_q = add( shl( exp, 1 ), 1 );
+ imag_sum = W_mult_32_32( prev_imag_fx[k], prev_imag_fx[k] );
+ rat_imag_sum_q = add( shl( exp, 1 ), 1 );
+ temp_64 = W_add( real_sum, imag_sum );
+ lshift = W_norm( temp_64 );
+ temp_32 = W_extract_h( W_shl( temp_64, lshift ) );
+ sqrt_exp = sub( add( shl( exp, 1 ), lshift ), 31 );
+ sqrt_exp = sub( 31, sqrt_exp );
+ urh_fx[k] = Sqrt32( temp_32, &sqrt_exp );
+ urh_exp[k] = sub( 31, sqrt_exp );
+ // In Float the condition is if ( urh[k] < EPSILON )
+ IF( EQ_32( urh_fx[k], 0 ) )
+ {
+ /* zero encountered */
+ BREAK;
+ }
+
+ uth_fx[k] = L_shl( BASOP_util_atan2( prev_imag_fx[k], prev_real_fx[k], 0 ), 15 ); // Q28
+ /* phase unwrap */
+ IF( EQ_32( k, 0 ) )
+ {
+ uthu_fx[0] = uth_fx[0];
+ }
+ ELSE
+ {
+ /* phase unwrap */
+ ph_diff_fx = L_sub( uth_fx[k], uth_fx[k - 1] );
+
+ uthu_fx[k] = uth_fx[k];
+ Word32 quot_fx_durho;
+ Word16 s = 0, s_diff;
+ Word32 add_fact, quo_sq;
+ IF( GE_32( L_abs( ph_diff_fx ), L_shr( PI2_FX, 2 ) ) )
+ {
+ temp_32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ph_diff_fx, PI2_FX, &s ) ); // Q(31)
+ ph_adj_t_fx = ( temp_32 == ONE_IN_Q30 ) ? L_sub( ONE_IN_Q31, 1 ) : L_shl( temp_32, s );
+ IF( EQ_32( L_abs( L_sub( L_add( ph_adj_t_fx, 1 ), L_shr( ph_adj_t_fx, 31 ) ) ), ONE_IN_Q30 ) )
+ {
+ ph_adj_t_fx = L_shr( ph_adj_t_fx, 31 );
+ }
+ add_fact = ( L_abs( ph_adj_t_fx ) >= ONE_IN_Q30 ) ? ( ( ph_adj_t_fx < 0 ) ? 1686629713 : -1686629713 ) : 0;
+ ph_adj_fx = W_add( add_fact, ph_adj_fx ); // Q28
+ }
+ /* unwrapped phase in uthu */
+ uthu_fx[k] = W_add( uthu_fx[k], ph_adj_fx ); // Q28
+ /* mean and stdev of per-sample magnitude ratios */
+ s_diff = sub( urh_exp[k - 1], urh_exp[k] );
+ temp_16 = BASOP_Util_Divide3232_Scale( urh_fx[k], urh_fx[k - 1], &s );
+ quot_fx = L_shl( temp_16, 16 ); // Q(31-s)
+ quot_exp[k] = sub( sub( 31, s_diff ), s );
+ quot_fx_durho = quot_fx;
+ drho_exp[k] = quot_exp[k];
+ IF( GE_32( k, 2 ) )
+ {
+ IF( LT_16( drho_exp[k - 1], drho_exp[k] ) )
+ {
+ quot_fx_durho = L_shr( quot_fx_durho, sub( drho_exp[k], drho_exp[k - 1] ) );
+ drho_exp[k] = drho_exp[k - 1];
+ }
+ ELSE IF( GT_16( drho_exp[k - 1], drho_exp[k] ) )
+ {
+ drho_fx = W_shr( drho_fx, sub( drho_exp[k - 1], drho_exp[k] ) );
+ }
+ }
+ drho_fx = W_add( quot_fx_durho, drho_fx ); // Q(31-s)
+ srho_exp[k] = sub( 31, shl( add( s_diff, s ), 1 ) );
+ quo_sq = Mpy_32_32( quot_fx, quot_fx );
+ IF( GE_32( k, 2 ) )
+ {
+ IF( LT_16( srho_exp[k - 1], srho_exp[k] ) )
+ {
+ quo_sq = L_shr( quo_sq, sub( srho_exp[k], srho_exp[k - 1] ) );
+ srho_exp[k] = srho_exp[k - 1];
+ }
+ ELSE IF( GT_16( srho_exp[k - 1], srho_exp[k] ) )
+ {
+ srho_fx = W_shr( srho_fx, sub( srho_exp[k - 1], srho_exp[k] ) );
+ }
+ }
+ srho_fx = W_add( srho_fx, quo_sq ); // Q(31-s)
+ diff_fx = W_sub( uthu_fx[k], uthu_fx[k - 1] ); // Q28 /* the mean value calculation could be optimized */
+
+ dth_fx = W_add( dth_fx, diff_fx ); // Q28
+ temp_32 = W_extract_l( diff_fx );
+ sth_fx = W_add( sth_fx, (Word64) Mpy_32_32( temp_32, temp_32 ) ); // Q25
+
+ /* mean and stdev of per-sample phase differences */
+ }
+ }
+
+ Word16 tmp_e, tmp, drho_sqr_q, temp_q;
+ Word32 divide_fact, drho_32, drho_sqr, dth_sqr;
+ IF( EQ_32( k, iNumCols ) )
+ {
+
+ tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e );
+ divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31
+ /* mean and stdev of per-sample magnitude ratios */
+ lshift = W_norm( drho_fx );
+ tmp_e = drho_exp[k - 1];
+ IF( LT_16( lshift, 32 ) )
+ {
+ drho_fx = W_shl( drho_fx, lshift );
+ tmp_e = add( tmp_e, lshift );
+ }
+ drho_32 = W_extract_h( drho_fx ); // Qtmp_e-32
+ drho_32 = Mpy_32_32( drho_32, divide_fact );
+ drho_sqr = Mpy_32_32( drho_32, drho_32 ); // Q(2*(tmp_e -32) - 31)
+ temp_64 = W_mult_32_32( sub( iNumCols, 1 ), drho_sqr ); // Q(2*(tmp_e -32) - 30)
+ drho_sqr_q = sub( shl( sub( tmp_e, 32 ), 1 ), 30 );
+ temp_q = srho_exp[k - 1];
+ IF( GT_16( srho_exp[k - 1], drho_sqr_q ) )
+ {
+ temp_64 = W_shl( temp_64, sub( srho_exp[k - 1], drho_sqr_q ) );
+ temp_q = srho_exp[k - 1];
+ }
+ ELSE IF( GT_16( drho_sqr_q, srho_exp[k - 1] ) )
+ {
+ srho_fx = W_shl( srho_fx, sub( drho_sqr_q, srho_exp[k - 1] ) );
+ temp_q = drho_sqr_q;
+ }
+ temp_64 = W_sub( srho_fx, temp_64 );
+ drho_q = sub( tmp_e, 32 );
+ IF( GT_64( temp_64, 0 ) )
+ {
+ lshift = W_norm( temp_64 );
+ temp_32 = W_extract_h( W_shl( temp_64, lshift ) );
+ sqrt_exp = sub( add( temp_q, lshift ), 32 );
+ tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e );
+ divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31
+ temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp
+ sqrt_exp1 = sub( 31, sqrt_exp );
+ srho_fx = Sqrt32( temp_32, &sqrt_exp1 );
+ srho_q = sub( 31, sqrt_exp1 );
+ }
+ ELSE
+ {
+ srho_q = 31;
+ srho_fx = 0;
+ }
+ /* mean and stdev of per-sample phase differences */
+ tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e );
+ divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31
+ /* mean and stdev of per-sample phase differences */
+ lshift = W_norm( dth_fx );
+ dth_fx = W_shl( dth_fx, lshift ); // Q28+lshift
+ dth32 = W_extract_h( dth_fx ); // Q28+lshift-32
+ dth_q = sub( add( 28, lshift ), 32 );
+ dth32 = Mpy_32_32( dth32, divide_fact );
+ dth_sqr = Mpy_32_32( dth32, dth32 ); // Q28+lshift-32
+ temp_64 = W_mult_32_32( sub( iNumCols, 1 ), dth_sqr ); // Q(2*lshift-39)
+ temp_q = sub( sub( shl( lshift, 1 ), 8 ), 30 );
+ // printf( "%f \t", temp );
+ IF( GT_16( temp_q, 25 ) )
+ {
+
+ sth_fx = W_shl( sth_fx, sub( temp_q, 25 ) );
+ }
+ ELSE IF( GT_16( 25, temp_q ) )
+ {
+ temp_64 = W_shl( temp_64, sub( 25, temp_q ) );
+ temp_q = 25;
+ }
+
+ temp_64 = W_sub( sth_fx, temp_64 );
+ IF( GT_64( temp_64, 0 ) )
+ {
+ lshift = W_norm( temp_64 );
+ temp_32 = W_extract_h( W_shl( temp_64, lshift ) );
+ sqrt_exp = sub( add( temp_q, lshift ), 32 );
+ tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e );
+ divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31
+ temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp
+ sqrt_exp1 = sub( 31, sqrt_exp );
+ sth_fx = Sqrt32( temp_32, &sqrt_exp1 );
+ sth_q = sub( 31, sqrt_exp1 );
+ }
+ ELSE
+ {
+ sth_fx = 0;
+ sth_q = 31;
+ }
+
+ /* do phase extension only IF the std deviations are small */
+ IF( LT_64( srho_fx, W_shl( SRHO_THRESH_FX, sub( srho_q, 31 ) ) ) || LT_64( sth_fx, W_shl( STH_THRESH_FX, sub( sth_q, 31 ) ) ) )
+ {
+ dth32 = L_shl( Mpy_32_32( dth32, PI_CONST ), sub( 31, dth_q ) ); // Q28+lshift-32-16
+ dth16 = extract_h( dth32 );
+ fac_ph_real_fx = L_deposit_h( getCosWord16R2( dth16 ) );
+ fac_ph_imag_fx = L_deposit_h( getSineWord16R2( dth16 ) );
+ ///* calculate complex evolution factor */
+ fac_real_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_real_fx ); // Qdrho_exp
+ fac_imag_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_imag_fx ); // Qdrho_exp
+#if START_VAL_AVG_LEN > 1
+ /* Calculate start value FOR evolution from last samples of previous frame */
+ fac_powj_real_fx = fac_real_fx;
+ fac_powj_imag_fx = fac_imag_fx;
+ start_real_fx = prev_real_fx[iNumCols - 1];
+ start_imag_fx = prev_imag_fx[iNumCols - 1];
+ FOR( j = 1; j < START_VAL_AVG_LEN; j++ )
+ {
+ start_real_fx = L_add( L_shr( start_real_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_sub( Mpy_32_32( fac_powj_real_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_imag_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31)
+ start_imag_fx = L_add( L_shr( start_imag_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_add( Mpy_32_32( fac_powj_imag_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_real_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31)
+ temp_fx = L_shl( L_sub( Mpy_32_32( fac_powj_real_fx, fac_real_fx ), Mpy_32_32( fac_powj_imag_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q
+ fac_powj_imag_fx = L_shl( L_add( Mpy_32_32( fac_powj_imag_fx, fac_real_fx ), Mpy_32_32( fac_powj_real_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q
+ fac_powj_real_fx = temp_fx;
+ }
+ start_q = sub( add( drho_q, exp ), 30 );
+#else
+ /* take last sample of previous frame as start value */
+ start_real = prev_real[iNumCols - 1];
+ start_imag = prev_imag[iNumCols - 1];
+#endif
+
+#if DO_PERTURB != 0
+
+ /* make evolution less static: apply per samples differences as in preceding frame */
+ rat_real_fx = W_add( W_mult_32_32( prev_real_fx[1], prev_real_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_imag_fx[0] ) ); // 2*exp
+ rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[1], prev_imag_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_real_fx[0] ) ); // 2*exp
+
+#if PH_PERT_ONLY != 0
+
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx );
+ rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx );
+ rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ temp_32 = W_extract_h( temp_64 );
+ sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+ /* only phase perturbation */
+ sqrt_exp = sub( 31, sqrt_exp );
+ tmp_e = 0;
+ abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp)
+
+ lshift = norm_l( drho_32 );
+ drho_32 = L_shl( drho_32, lshift );
+ drho_q = add( drho_q, lshift );
+ IF( EQ_16( drho_q, 31 ) )
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( ONE_IN_Q31, drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ ELSE
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( L_shl( 1, drho_q ), drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e );
+
+ rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx );
+
+ rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx );
+ rat_real_q = add( add( rat_real_q, temp_16 ), 1 );
+
+ rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 );
+
+#else
+ /* phase and magnitude perturbation */
+ abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) );
+ rat_real *= abs2inv;
+ rat_imag *= abs2inv;
+#endif
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( rat_real_q, lshift ), 32 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( rat_imag_q, lshift ), 32 );
+
+ /* apply complex evolution FOR first substitution sample */
+
+ real_sum = W_mult_32_32( rat_real32_fx, start_real_fx );
+ rat_real_sum_q = add( add( rat_real_q, start_q ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, start_imag_fx );
+ rat_imag_sum_q = add( add( rat_imag_q, start_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_sub( real_sum, imag_sum );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_real_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_real_exp[0] = sub( add( sqrt_exp, lshift ), 32 );
+
+ real_sum = W_mult_32_32( rat_imag32_fx, start_real_fx );
+ rat_real_sum_q = add( add( rat_imag_q, start_q ), 1 );
+ imag_sum = W_mult_32_32( rat_real32_fx, start_imag_fx );
+ rat_imag_sum_q = add( add( rat_real_q, start_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_add( real_sum, imag_sum );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_imag_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_imag_exp[0] = sub( add( sqrt_exp, lshift ), 32 );
+ FOR( j = 2; j < iNumCols; j++ )
+ {
+ rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp
+ rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp
+#if PH_PERT_ONLY != 0
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx );
+ rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx );
+ rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+
+ temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ temp_32 = W_extract_h( temp_64 );
+ sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+ /* only phase perturbation */
+ sqrt_exp = sub( 31, sqrt_exp );
+ tmp_e = 0;
+ abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp)
+
+ IF( EQ_16( drho_q, 31 ) )
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ ELSE
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e );
+
+ rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx );
+ rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx );
+ rat_real_q = add( add( rat_real_q, temp_16 ), 1 );
+ rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 );
+
+#else
+ /* phase and magnitude perturbation */
+ abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) );
+#endif
+
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( rat_real_q, lshift ), 32 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( rat_imag_q, lshift ), 32 );
+
+
+ real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j - 2] );
+ rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j - 2] ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j - 2] );
+ rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j - 2] ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_real_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_real_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+
+ real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j - 2] );
+ rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j - 2] ), 1 );
+ imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j - 2] );
+ rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j - 2] ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_imag_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_imag_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+ }
+
+ /* do the same FOR samples of crossfade region */
+ FOR( j = 1; j < CLDFB_PLC_XF + 2; j++ )
+ {
+ rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp
+ rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp
+
+#if PH_PERT_ONLY != 0
+
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 );
+ real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx );
+ rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx );
+ rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ temp_32 = W_extract_h( temp_64 );
+ sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+ /* only phase perturbation */
+ sqrt_exp = sub( 31, sqrt_exp );
+ tmp_e = 0;
+ abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp)
+
+ IF( EQ_16( drho_q, 31 ) )
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ ELSE
+ {
+ abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e
+ }
+ temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e );
+ rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx );
+ rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx );
+ rat_real_q = add( add( rat_real_q, temp_16 ), 1 );
+ rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 );
+#else
+ abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) );
+#endif
+ lshift = W_norm( rat_real_fx );
+ temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift
+ rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_real_q = sub( add( rat_real_q, lshift ), 32 );
+ lshift = W_norm( rat_imag_fx );
+ temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift
+ rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31
+ rat_imag_q = sub( add( rat_imag_q, lshift ), 32 );
+
+
+ real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j + iNumCols - 3] );
+ rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j + iNumCols - 3] ), 1 );
+ imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j + iNumCols - 3] );
+ rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j + iNumCols - 3] ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_real_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_real_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+
+ real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j + iNumCols - 3] );
+ rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j + iNumCols - 3] ), 1 );
+ imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j + iNumCols - 3] );
+ rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j + iNumCols - 3] ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( temp_64 );
+ temp_64 = W_shl( temp_64, lshift );
+ rec_imag_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32
+ rec_imag_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 );
+ }
+#else
+ rec_real[0] = fac_real * start_real - fac_imag * start_imag;
+ rec_imag[0] = fac_imag * start_real + fac_real * start_imag;
+ FOR( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ )
+ {
+ rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1];
+ rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1];
+ }
+#endif
+
+#if CLDFB_PLC_XF > 0
+ /* apply crossfade */
+ FOR( j = 0; j < CLDFB_PLC_XF; j++ )
+ {
+ rec_real_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_real_fx[iNumCols + j] );
+ rec_imag_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_imag_fx[iNumCols + j] );
+ xf_bet_fx[j] = L_sub( ONE_IN_Q31, xf_alp_fx[j] );
+ }
+#endif
+ }
+ ELSE
+ {
+ Word16 guard_bits = find_guarded_bits_fx( iNumCols );
+ /* do complex lpc combined with frame repetition */
+ Ruu_real_fx[0] = W_add( W_shr( W_mult_32_32( prev_real_fx[0], prev_real_fx[0] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[0], prev_imag_fx[0] ), guard_bits ) );
+ Ruu_real_fx[1] = 0;
+ Ruu_imag_fx[1] = 0;
+ FOR( j = 1; j < iNumCols; j++ )
+ {
+ Ruu_real_fx[0] = W_add( Ruu_real_fx[0], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j] ), guard_bits ) ) );
+ Ruu_real_fx[1] = W_add( Ruu_real_fx[1], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) );
+ Ruu_imag_fx[1] = W_add( Ruu_imag_fx[1], W_sub( W_shr( W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_real_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) );
+ }
+ // printf( "%.7f \t", Ruu_real[1]
+ lshift = W_norm( Ruu_real_fx[0] );
+ Ruu_real_fx_0 = W_extract_h( W_shl( Ruu_real_fx[0], lshift ) );
+ Ruu_real_fx_0_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 );
+ lshift = W_norm( Ruu_real_fx[0] );
+ Ruu_real_fx_1 = W_extract_h( W_shl( Ruu_real_fx[1], lshift ) );
+ Ruu_real_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 );
+ lshift = W_norm( Ruu_real_fx[0] );
+ Ruu_imag_fx_1 = W_extract_h( W_shl( Ruu_imag_fx[1], lshift ) );
+ Ruu_imag_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 );
+ IF( GT_64( Ruu_real_fx[0], 0 ) )
+ {
+ /* prediction coefficient */
+ fac_real_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_real_fx_1, Ruu_real_fx_0, &tmp_e ) );
+ fac_real_q = sub( add( sub( 31, tmp_e ), Ruu_real_fx_1_q ), Ruu_real_fx_0_q );
+ fac_imag_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_imag_fx_1, Ruu_real_fx_0, &tmp_e ) );
+ fac_imag_q = sub( add( sub( 31, tmp_e ), Ruu_imag_fx_1_q ), Ruu_real_fx_0_q );
+ }
+ ELSE
+ {
+ fac_imag_fx = 0;
+ fac_imag_q = 31;
+ fac_real_fx = 0;
+ fac_real_q = 31;
+ }
+
+ /* apply prediction using last sample of preceding frame as start value and combine with previous frame samples */
+ fac_powj_real_fx = fac_real_fx;
+ fac_powj_imag_fx = fac_imag_fx;
+
+ Word16 powj_real_q = fac_real_q;
+ Word16 powj_imag_q = fac_imag_q;
+
+ real_sum = W_mult_32_32( fac_real_fx, fac_real_fx );
+ rat_real_sum_q = add( shl( fac_real_q, 1 ), 1 );
+ imag_sum = W_mult_32_32( fac_imag_fx, fac_imag_fx );
+ rat_imag_sum_q = add( shl( fac_imag_q, 1 ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ sqrt_exp = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ sqrt_exp = rat_real_sum_q;
+ }
+ abs_fac_fx = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) );
+ lshift = W_norm( abs_fac_fx );
+ abs_fac_32 = W_extract_h( W_shl( abs_fac_fx, lshift ) );
+ sqrt_exp = sub( 31, ( sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ) ) );
+ abs_fac_32 = Sqrt32( abs_fac_32, &sqrt_exp );
+ sqrt_exp = sub( 31, sqrt_exp );
+ abs_fac_32 = L_shr( abs_fac_32, sub( sqrt_exp, 31 ) ); // Q31
+ sqrt_exp = 31;
+ abs_fac_powj_32 = L_shr( abs_fac_32, 1 ); // Q30
+ sqrt_exp = 30;
+
+ FOR( j = 0; j < iNumCols; j++ )
+ {
+ comp_fac_fx = L_sub( L_shl( 1, sqrt_exp ), abs_fac_powj_32 );
+ real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_real_fx );
+ rat_real_sum_q = add( add( exp, powj_real_q ), 1 );
+ imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_imag_fx );
+ rat_imag_sum_q = add( add( exp, powj_imag_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ rat_real_sum_q = sub( rat_real_sum_q, guard_bits );
+ imag_sum = W_mult_32_32( prev_real_fx[j], comp_fac_fx );
+ rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ lshift = W_norm( real_sum );
+ rec_real_fx[j] = W_extract_h( W_shl( real_sum, lshift ) );
+ rec_real_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+ real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_imag_fx );
+ rat_real_sum_q = add( add( exp, powj_imag_q ), 1 );
+ imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_real_fx );
+ rat_imag_sum_q = add( add( exp, powj_real_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ rat_real_sum_q = sub( rat_real_sum_q, guard_bits );
+ imag_sum = W_mult_32_32( prev_imag_fx[j], comp_fac_fx );
+ rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+
+ lshift = W_norm( real_sum );
+ rec_imag_fx[j] = W_extract_h( W_shl( real_sum, lshift ) );
+ rec_imag_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+
+ abs_fac_powj_32 = Mpy_32_32( abs_fac_powj_32, abs_fac_32 );
+
+
+ real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx );
+ rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 );
+ imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx );
+ rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ // rat_real_sum_q = rat_real_sum_q - 1;
+ lshift = W_norm( real_sum );
+ temp_32 = W_extract_h( W_shl( real_sum, lshift ) );
+ temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+
+ real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx );
+ rat_real_sum_q = fac_imag_q + powj_real_q + 1;
+ imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx );
+ rat_imag_sum_q = fac_real_q + powj_imag_q + 1;
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ // rat_real_sum_q = rat_real_sum_q - 1;
+ lshift = W_norm( real_sum );
+ fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) );
+ powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+
+ fac_powj_real_fx = temp_32;
+ powj_real_q = temp_16;
+ }
+
+
+ /* prepare XF to next frame using prediction */
+ fac_powj_real_fx = fac_real_fx;
+ fac_powj_imag_fx = fac_imag_fx;
+ powj_real_q = fac_real_q;
+ powj_imag_q = fac_imag_q;
+ abs_fac_powj_32 = abs_fac_32; // Q30
+ sqrt_exp = 31;
+#if CLDFB_PLC_XF > 0
+ guard_bits = find_guarded_bits_fx( CLDFB_PLC_XF );
+ FOR( j = 0; j < CLDFB_PLC_XF; j++ )
+ {
+
+
+ xf_bet_fx[j] = L_sub( ONE_IN_Q31, abs_fac_powj_32 );
+ real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_real_fx );
+ rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_real_q ), 1 );
+ imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_imag_fx );
+ rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_imag_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ rat_real_sum_q = sub( rat_real_sum_q, guard_bits );
+
+ lshift = W_norm( real_sum );
+ rec_real_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) );
+ rec_real_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 );
+
+ real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_imag_fx );
+ rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_imag_q ), 1 );
+ imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_real_fx );
+ rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_real_q ), 1 );
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ /*sqrt_exp = rat_real_sum_q;*/
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ rat_real_sum_q = sub( rat_real_sum_q, guard_bits );
+
+ lshift = W_norm( real_sum );
+ rec_imag_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) );
+ rec_imag_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 );
+
+ abs_fac_powj_32 = W_extract_h( W_mult_32_32( abs_fac_powj_32, abs_fac_32 ) ); // Q31
+
+ real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx );
+ rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 );
+ imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx );
+ rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ }
+ real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ lshift = W_norm( real_sum );
+ temp_32 = W_extract_h( W_shl( real_sum, lshift ) );
+ temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+
+ real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx );
+ rat_real_sum_q = add( add( fac_imag_q, powj_real_q ), 1 );
+ imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx );
+ rat_imag_sum_q = add( add( fac_real_q, powj_imag_q ), 1 );
+
+ IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) )
+ {
+ real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) );
+ rat_real_sum_q = rat_imag_sum_q;
+ }
+ ELSE
+ {
+ imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) );
+ }
+ real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) );
+ lshift = W_norm( real_sum );
+ fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) );
+ powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 );
+
+ fac_powj_real_fx = temp_32;
+ powj_real_q = temp_16;
+ }
+#endif
+ }
+ }
+ ELSE
+ {
+ FOR( j = 0; j < iNumCols; j++ )
+ {
+ rec_real_fx[j] = prev_real_fx[j];
+ rec_real_exp[j] = exp;
+ rec_imag_fx[j] = prev_imag_fx[j];
+ rec_imag_exp[j] = exp;
+ }
+#if CLDFB_PLC_XF > 0
+ FOR( j = 0; j < CLDFB_PLC_XF; j++ )
+ {
+ xf_bet_fx[j] = ONE_IN_Q31;
+ rec_real_fx[j + iNumCols] = 0;
+ rec_real_exp[j + iNumCols] = 31;
+ rec_imag_fx[j + iNumCols] = 0;
+ rec_imag_exp[j + iNumCols] = 31;
+ }
+#endif
+ }
+ return;
+}
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinRendPLCOpen()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error isar_splitBinRendPLCOpen(
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC,
+ Word16 iNumSubSets )
+{
+ ivas_error error;
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC;
+
+ error = IVAS_ERR_OK;
+ IF( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) );
+ }
+
+ hSplitRendPLC->prev_bfi = 0;
+ hSplitRendPLC->bf_count = 0;
+ hSplitRendPLC->iNumSubSets = iNumSubSets;
+
+ set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX );
+ set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX );
+
+ *phSplitRendPLC = hSplitRendPLC;
+
+ return error;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinRendPLCClose()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinRendPLCClose(
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC )
+{
+ if ( ( *phSplitRendPLC ) != NULL )
+ {
+ free( ( *phSplitRendPLC ) );
+ ( *phSplitRendPLC ) = NULL;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinRendPLCsaveState()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinRendPLCsaveState(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 num_chs,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations )
+{
+ Word16 k, n;
+
+ /* Save Cldfb frame */
+ FOR( k = 0; k < ( iNumBlocks * iNumIterations ); k++ )
+ {
+ FOR( n = 0; n < num_chs; n++ )
+ {
+ mvl2l( &Cldfb_RealBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][0], CLDFB_NO_CHANNELS_MAX );
+ mvl2l( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][0], CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinRendPLC_xf()
+ *
+ * Cross-fade of preceding bad frame into good frame
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinRendPLC_xf_fx(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 num_chs,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations,
+ Word32 **ppiDecodingFailed,
+ Word32 **ppiDecodingFailedPrev,
+ Word16 exp )
+{
+ Word16 n, i, k;
+ /* Indicate that next transition will be from a good frame */
+ hSplitRendPLC->prev_bfi = 0;
+ move16();
+
+ /* Reset bf conter */
+ hSplitRendPLC->bf_count = 0;
+ move16();
+
+ /* Do the cross fade */
+ FOR( n = 0; n < num_chs; n++ )
+ {
+ FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
+ {
+ Word32 iSubSet = i % hSplitRendPLC->iNumSubSets;
+ test();
+ IF( EQ_32( ppiDecodingFailedPrev[n][iSubSet], 1 ) && EQ_32( ppiDecodingFailed[n][iSubSet], 0 ) )
+ {
+#if CLDFB_PLC_XF > 0
+ FOR( k = 0; k < CLDFB_PLC_XF; k++ )
+ {
+ Word32 L_tmp;
+ Word64 W_tmp;
+ Word16 shift;
+ W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_RealBuffer_Binaural_fx[n][k][i] ), 1 );
+ W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) );
+
+ shift = W_norm( W_tmp );
+ W_tmp = W_shl( W_tmp, shift );
+ L_tmp = W_extract_h( W_tmp );
+ L_tmp = L_shr( L_tmp, 31 + shift - 32 );
+ Cldfb_RealBuffer_Binaural_fx[n][k][i] = L_tmp;
+
+ W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_ImagBuffer_Binaural_fx[n][k][i] ), 1 );
+ W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) );
+
+ shift = W_norm( W_tmp );
+ W_tmp = W_shl( W_tmp, shift );
+ L_tmp = W_extract_h( W_tmp );
+ L_tmp = L_shr( L_tmp, 31 + shift - 32 );
+ Cldfb_ImagBuffer_Binaural_fx[n][k][i] = L_tmp;
+ }
+#endif
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinRendPLC()
+ *
+ * Conceal bad frame
+ *------------------------------------------------------------------------*/
+void isar_splitBinRendPLC(
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 num_chs,
+ const Word16 iNumBlocks,
+ const Word16 iNumIterations,
+ int32_t **ppiDecodingFailed,
+ Word16 exp )
+{
+ Word32 i, n, k;
+ Word32 temp_32, fade_fac_fx;
+ Word16 div_exp = 0, tmp, exp_fade, frac;
+ Word32 prev_real_fx[CLDFB_NO_COL_MAX], prev_imag_fx[CLDFB_NO_COL_MAX], rec_real_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];
+ Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];
+#if CLDFB_PLC_XF > 0
+ Word32 xf_alp_fx[CLDFB_PLC_XF];
+#endif
+ Word16 iNumCols, fade_start_cntr, mute_cntr, fade_val;
+
+ iNumCols = extract_l( L_mult0( iNumBlocks, iNumIterations ) );
+
+ /* Indicate that next transition will be from a bad frame */
+ hSplitRendPLC->prev_bfi = 1;
+
+
+#if CLDFB_PLC_XF > 0
+ FOR( i = 0; i < CLDFB_PLC_XF; i++ )
+ {
+ xf_alp_fx[i] = xf_alp_tab[i];
+ }
+#endif
+ Word16 exp1 = exp;
+
+ FOR( n = 0; n < num_chs; n++ )
+ {
+ FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
+ {
+ Word32 iSubSet = i % hSplitRendPLC->iNumSubSets;
+ FOR( k = 0; k < iNumCols; k++ )
+ {
+ prev_real_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx );
+ prev_imag_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx );
+ }
+ adaptive_polar_ext_plc_fx(
+ prev_real_fx, prev_imag_fx, rec_real_fx, rec_imag_fx,
+ rec_real_exp, rec_imag_exp
+#if CLDFB_PLC_XF > 0
+ ,
+ xf_alp_fx, hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i],
+#endif
+ exp,
+ iNumCols );
+
+ Word16 temp16;
+
+ FOR( k = 0; k < iNumCols; k++ )
+ {
+ temp16 = sub( rec_real_exp[k], exp1 );
+ rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 );
+ rec_real_exp[k] = sub( rec_real_exp[k], temp16 );
+
+ temp16 = sub( rec_imag_exp[k], exp1 );
+ rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 );
+ rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 );
+ // Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k];
+ hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp
+ // Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k] ;
+ hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp
+ if ( ppiDecodingFailed[n][iSubSet] == 1 )
+ { /* only then copy to output */
+ Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k];
+ Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k];
+ }
+ }
+
+#if CLDFB_PLC_XF > 0
+ FOR( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ )
+ {
+
+ temp16 = sub( rec_real_exp[k], exp1 );
+ rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 );
+ rec_real_exp[k] = sub( rec_real_exp[k], temp16 );
+
+ temp16 = sub( rec_imag_exp[k], exp1 );
+ rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 );
+ rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 );
+ /*TODO: Will remove the inter conversion later*/
+ hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp
+ hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp
+ }
+#endif
+ }
+ }
+
+
+ /* Check bf counter */
+ tmp = BASOP_Util_Divide1616_Scale( PLC_FADE_CNST, iNumCols, &div_exp );
+ fade_start_cntr = shr( tmp, ( 15 - div_exp ) );
+ tmp = BASOP_Util_Divide1616_Scale( PLC_MUTE_CNST, iNumCols, &div_exp );
+ mute_cntr = shr( tmp, ( 15 - div_exp ) );
+
+ IF( GE_16( hSplitRendPLC->bf_count++, fade_start_cntr ) )
+ {
+ IF( LT_16( hSplitRendPLC->bf_count, mute_cntr ) )
+ {
+ fade_val = extract_l( L_shr( L_mult0( sub( hSplitRendPLC->bf_count, fade_start_cntr ), iNumCols ), 4 ) ); // Q0
+ temp_32 = L_mult( -16328, fade_val ); // Q15
+ temp_32 = L_shl( temp_32, 1 ); // Q16
+
+ frac = L_Extract_lc( temp_32, &exp_fade ); /* Extract exponent of temp_32 */
+ fade_fac_fx = Pow2( 14, frac ); /* Put 14 as exponent so that */
+ exp_fade = 31 - add( sub( exp_fade, 14 ), 16 );
+ fade_fac_fx = L_shl( fade_fac_fx, 31 - exp_fade ); // Q31
+
+ FOR( n = 0; n < num_chs; n++ )
+ {
+ FOR( k = 0; k < iNumCols; k++ )
+ {
+ v_multc_fixed( &Cldfb_RealBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_RealBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX );
+ v_multc_fixed( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_ImagBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( n = 0; n < num_chs; n++ )
+ {
+ FOR( k = 0; k < iNumCols; k++ )
+ {
+ set_val_Word32( &Cldfb_RealBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX );
+ set_val_Word32( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+ hSplitRendPLC->bf_count = mute_cntr;
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c
new file mode 100644
index 0000000000000000000000000000000000000000..1bbff0b5cca78d1a1764e3489f34095266d5f41a
--- /dev/null
+++ b/lib_isar/isar_splitRendererPost.c
@@ -0,0 +1,2131 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+#include
+#endif
+#include "ivas_prot.h"
+#include "prot.h"
+#include "isar_rom_post_rend.h"
+#include "isar_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "prot_fx2.h"
+#include "wmc_auto.h"
+#include "basop_util.h"
+#define Q31_BY_360 ( 5965232 ) // Q31
+
+
+/*-------------------------------------------------------------------------
+ * isar_splitBinPostRendOpen()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error isar_splitBinPostRendOpen(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word32 output_Fs )
+{
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend;
+ ivas_error error;
+ Word16 ch;
+
+ IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) );
+ }
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ hBinRend->cldfbSyn[ch] = NULL;
+ hBinRend->cldfbAna[ch] = NULL;
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ )
+ {
+ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ hBinRend->cldfbSynReconsBinDec[i][ch] = NULL;
+ }
+ }
+#endif
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ IF( ( error = openCldfb_splitRend( &( hBinRend->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ IF( ( error = openCldfb_splitRend( &( hBinRend->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ )
+ {
+ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+#endif
+ hBinRend->cf_flag = 0;
+ set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData );
+ set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData );
+ isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
+ *hBinHrSplitPostRend = hBinRend;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------------
+ * isar_splitBinPostRendClose()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinPostRendClose(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend )
+{
+ Word16 ch;
+
+ IF( ( *hBinHrSplitPostRend ) != NULL )
+ {
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ IF( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL )
+ {
+ deleteCldfb_splitRend( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) );
+ ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL;
+ }
+ IF( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL )
+ {
+ deleteCldfb_splitRend( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) );
+ ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL;
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ )
+ {
+ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL )
+ {
+ deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) );
+ ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL;
+ }
+ }
+ }
+#endif
+
+ free( ( *hBinHrSplitPostRend ) );
+ ( *hBinHrSplitPostRend ) = NULL;
+ }
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_split_rend_huffman_decode_opt()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+static Word16 ivas_split_rend_huffman_decode_opt(
+ isar_split_rend_huffman_cfg_t *huff_cfg,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word16 *idx_trav_list )
+{
+ Word32 i, ind, code, num_bits, code_b, num_bits_read;
+ const Word32 *codebook;
+
+ codebook = huff_cfg->codebook;
+ num_bits_read = 0;
+ move32();
+ ind = L_sub( huff_cfg->codebook[0], 1 );
+ code = 0;
+ move32();
+ FOR( i = 0; i < huff_cfg->sym_len; i++ )
+ {
+ codebook = codebook + idx_trav_list[i] * 3;
+ num_bits = codebook[1];
+ move32();
+ code_b = codebook[2];
+ move32();
+ num_bits_read = L_sub( num_bits, num_bits_read );
+ code = L_shl( code, extract_l( num_bits_read ) );
+ IF( GT_32( num_bits_read, 0 ) )
+ {
+ code = L_or( code, ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ) );
+ }
+
+ IF( EQ_32( code, code_b ) )
+ {
+ ind = codebook[0];
+ move32();
+ BREAK;
+ }
+
+ num_bits_read = num_bits;
+ move32();
+ codebook = huff_cfg->codebook;
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ assert( ind >= huff_cfg->codebook[0] );
+#endif
+ return extract_l( ind );
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_split_rend_unquant_md()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+static void ivas_split_rend_unquant_md_fx(
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
+ ISAR_SPLIT_REND_POSE_TYPE pose_type,
+ Word16 real_only,
+ Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS],
+ const Word32 pred_quant_step )
+{
+ Word16 ch1, ch2;
+ Word16 gd_idx_min;
+
+ test();
+ IF( EQ_32( pose_type, PRED_ONLY ) || EQ_32( pose_type, PRED_ROLL_ONLY ) )
+ {
+ Word32 quantstep;
+
+ quantstep = pred_quant_step;
+ move32();
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */
+ move32();
+ hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */
+ move32();
+ }
+ }
+#endif
+
+ IF( real_only )
+ {
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */
+ move32();
+ hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, Q6 ) ); /* Q25 */
+ move32();
+ }
+ }
+#endif
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ hMd->pred_mat_im_fx[ch1][ch2] = 0; /* Q25 */
+ move32();
+ }
+ }
+ }
+ ELSE
+ {
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */
+ move32();
+ hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */
+ move32();
+ }
+ }
+#endif
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ hMd->pred_mat_im_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_im_idx[ch1][ch2], Q9 ) ) ); /* Q25 */
+ move32();
+ }
+ }
+ }
+ }
+ ELSE IF( EQ_32( pose_type, COM_GAIN_ONLY ) )
+ {
+ gd_idx_min = 0;
+ move16();
+ hMd->gd_idx = add( hMd->gd_idx, gd_idx_min );
+ hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_D_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */
+ }
+ ELSE IF( EQ_32( pose_type, LR_GAIN_ONLY ) )
+ {
+ gd_idx_min = 7;
+ move16();
+ hMd->gd_idx = add( hMd->gd_idx, gd_idx_min );
+ hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */
+
+ hMd->gd2_idx = add( hMd->gd2_idx, gd_idx_min );
+ hMd->gd2_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd2_idx, Q9 ) ) ); /* Q25 */
+ }
+ ELSE
+ {
+ hMd->gd_fx = 0; /* Q25 */
+ move32();
+ }
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_splitBinPostRendMdBase2Dec()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+static void isar_splitBinPostRendMdBase2Dec(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word16 num_subframes,
+ const Word16 pred_real_bands_yaw,
+ const Word16 pred_imag_bands_yaw,
+ const Word16 pred_quant_pnts_yaw,
+ const Word16 d_bands_yaw,
+ const Word16 bands_pitch,
+ const Word16 pred_real_bands_roll,
+ const Word16 pred_imag_bands_roll )
+{
+ Word16 sf_idx, pos_idx, b, ch1, ch2;
+ Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len;
+ Word16 min_pred_roll_idx, pred_roll_code_len;
+ Word16 pred_cb_idx;
+ Word16 code;
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
+
+ pHuff_cfg = &hBinHrSplitPostRend->huff_cfg;
+
+ IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
+ {
+ pred_cb_idx = 1;
+ move16();
+ }
+ ELSE
+ {
+ pred_cb_idx = 0;
+ move16();
+ }
+ min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
+ min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
+ min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] );
+ min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] );
+ pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx];
+ move16();
+ pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len;
+ move16();
+ gd_code_len = pHuff_cfg->gd_base2_code_len;
+ move16();
+ p_gd_code_len = pHuff_cfg->p_gd_base2_code_len;
+ move16();
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ )
+ {
+ IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) )
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx );
+ move16();
+ }
+ }
+ }
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) );
+ hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx );
+ move16();
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx );
+ move16();
+ }
+ }
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) );
+ hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx );
+ move16();
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_idx );
+ move16();
+ }
+ hMd->pred_mat_re_idx[0][1] = 0;
+ move16();
+ hMd->pred_mat_re_idx[1][0] = 0;
+ move16();
+ }
+#endif
+ FOR( b = 0; b < d_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len ) );
+ hMd->gd_idx = add( code, min_gd_idx );
+ move16();
+ }
+ }
+ ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) )
+ {
+ FOR( b = 0; b < bands_pitch; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) );
+ hMd->gd_idx = add( code, min_p_gd_idx );
+ move16();
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) );
+ hMd->gd2_idx = add( code, min_p_gd_idx );
+ move16();
+ }
+ }
+ ELSE
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx );
+ move16();
+ }
+ }
+ }
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) );
+ hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx );
+ move16();
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx );
+ move16();
+ }
+ }
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) );
+ hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx );
+ move16();
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) );
+ hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_roll_idx );
+ move16();
+ }
+ hMd->pred_mat_re_idx[0][1] = 0;
+ move16();
+ hMd->pred_mat_re_idx[1][0] = 0;
+ move16();
+ }
+#endif
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_splitBinPostRendMdHuffDec()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+static void ivas_splitBinPostRendMdHuffDec(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word16 num_subframes,
+ const Word16 pred_real_bands_yaw,
+ const Word16 pred_imag_bands_yaw,
+ const Word16 pred_quant_pnts_yaw,
+ const Word16 d_bands_yaw,
+ const Word16 bands_pitch,
+ const Word16 pred_real_bands_roll,
+ const Word16 pred_imag_bands_roll )
+{
+ Word16 pos_idx, b, sf_idx;
+ Word16 ch1, ch2;
+ Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 min_pred_idx, max_pred_idx;
+ Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
+
+ pHuff_cfg = &hBinHrSplitPostRend->huff_cfg;
+
+ IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
+ {
+ pred_cb_idx = 1;
+ move16();
+ }
+ ELSE
+ {
+ pred_cb_idx = 0;
+ move16();
+ }
+ min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
+ max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3] );
+
+ min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
+ max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3] );
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ )
+ {
+ IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) )
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx );
+ }
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx );
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx );
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx );
+ }
+ FOR( ; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
+ move16();
+ }
+ sym_adj_idx[1][0] = 0;
+ move16();
+ sym_adj_idx[0][1] = 0;
+ move16();
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx );
+ }
+#endif
+ FOR( b = 0; b < d_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav );
+ // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits );
+ }
+ }
+ ELSE IF( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ FOR( b = 0; b < bands_pitch; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
+ // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits );
+
+ hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
+ }
+ }
+ ELSE
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
+ }
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
+ move16();
+ // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
+ }
+ }
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
+ }
+ FOR( ; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
+ move16();
+ }
+ sym_adj_idx[1][0] = 0;
+ move16();
+ sym_adj_idx[0][1] = 0;
+ move16();
+ isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
+ }
+#endif
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_splitBinPostRendMdDec()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+void isar_splitBinPostRendMdDec_fx(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ,
+ BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend
+#endif
+)
+{
+ Word16 pos_idx, b, sf_idx, num_subframes, ch1;
+ Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word16 num_quant_strats;
+#else
+ Word16 num_complex_bands, num_quant_strats;
+#endif
+ Word32 quant_strat_bits, is_huff_coding, quant_strat;
+ Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q26
+ Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q31
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ Word16 ch1, ch2;
+#endif
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ ISAR_SPLIT_REND_CONFIG_DATA split_rend_config;
+ ISAR_SPLIT_REND_ROT_AXIS rot_axis;
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word16 ro_md_flag, num_bits, axis_code;
+#endif
+
+ hBinHrSplitPostRend->low_Res = 1;
+ move16();
+
+ split_rend_config.dof = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS ) );
+ split_rend_config.hq_mode = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS ) );
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof );
+ if ( num_bits > 0 )
+ {
+ axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits );
+ }
+ else
+ {
+ axis_code = 0;
+ }
+ rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code );
+ ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS );
+#else
+ rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS );
+#endif
+ isar_renderSplitGetMultiBinPoseData_fx( &split_rend_config, pMultiBinPoseData, rot_axis );
+
+ set_fix_rotation_mat_fx( hBinHrSplitPostRend->fix_pos_rot_mat_fx, pMultiBinPoseData );
+ set_pose_types_fx( hBinHrSplitPostRend->pose_type, pMultiBinPoseData );
+
+ num_subframes = EQ_16( hBinHrSplitPostRend->low_Res, 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1;
+ move16();
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ Word16 angle;
+
+ hBinHrSplitPostRend->QuaternionsPre[sf_idx].w_fx = -12582912; /* -3.0f in Q22 */
+ move32();
+
+ angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) );
+ angle = sub( angle, 180 );
+ hBinHrSplitPostRend->QuaternionsPre[sf_idx].x_fx = L_shl( angle, Q22 ); /* Q22 */
+ move32();
+
+ angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) );
+ angle = sub( angle, 180 );
+ hBinHrSplitPostRend->QuaternionsPre[sf_idx].y_fx = L_shl( angle, Q22 ); /* Q22 */
+ move32();
+
+ angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) );
+ angle = sub( angle, 180 );
+ hBinHrSplitPostRend->QuaternionsPre[sf_idx].z_fx = L_shl( angle, Q22 ); /* Q22 */
+ move32();
+ }
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ isar_split_rend_get_quant_params_fx(
+ MAX_SPLIT_REND_MD_BANDS,
+ pred_real_bands_yaw,
+ pred_imag_bands_yaw,
+ pred_quant_pnts_yaw,
+ pred_quantstep_yaw_fx,
+ pred_1byquantstep_yaw_fx,
+ d_bands_yaw,
+ bands_pitch,
+ pred_real_bands_roll,
+ pred_imag_bands_roll,
+ ro_md_flag,
+ &num_quant_strats );
+#else
+ isar_split_rend_get_quant_params_fx(
+ MAX_SPLIT_REND_MD_BANDS,
+ pred_real_bands_yaw,
+ pred_imag_bands_yaw,
+ pred_quant_pnts_yaw,
+ pred_quantstep_yaw_fx,
+ pred_1byquantstep_yaw_fx,
+ d_bands_yaw,
+ bands_pitch,
+ pred_real_bands_roll,
+ pred_imag_bands_roll,
+ &num_quant_strats,
+ &num_complex_bands );
+#endif
+ quant_strat_bits = L_deposit_l( ceil_log_2( num_quant_strats ) );
+ is_huff_coding = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
+ quant_strat = ISAR_SPLIT_REND_BITStream_read_int32( pBits, quant_strat_bits );
+
+ IF( EQ_32( is_huff_coding, 0 ) )
+ {
+ isar_splitBinPostRendMdBase2Dec(
+ pBits, hBinHrSplitPostRend,
+ pMultiBinPoseData,
+ num_subframes,
+ pred_real_bands_yaw[quant_strat],
+ pred_imag_bands_yaw[quant_strat],
+ pred_quant_pnts_yaw[quant_strat],
+ d_bands_yaw[quant_strat],
+ bands_pitch[quant_strat],
+ pred_real_bands_roll[quant_strat],
+ pred_imag_bands_roll[quant_strat] );
+ }
+ ELSE
+ {
+ ivas_splitBinPostRendMdHuffDec(
+ pBits, hBinHrSplitPostRend,
+ pMultiBinPoseData,
+ num_subframes,
+ pred_real_bands_yaw[quant_strat],
+ pred_imag_bands_yaw[quant_strat],
+ pred_quant_pnts_yaw[quant_strat],
+ d_bands_yaw[quant_strat],
+ bands_pitch[quant_strat],
+ pred_real_bands_roll[quant_strat],
+ pred_imag_bands_roll[quant_strat] );
+ }
+#ifdef SPLIT_MD_CODING_DEBUG
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ int16_t val, ch2, val_ref;
+ char filename[200] = "split_md_debug_indices.bin";
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW )
+ {
+ for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ for ( b = 0; b < bands_pitch[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx;
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ else
+ {
+ for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ dbgread( &val_ref, sizeof( int16_t ), 1, filename );
+ if ( abs( val_ref - val ) > 0 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ )
+ {
+ IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) )
+ {
+ FOR( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] );
+ }
+ FOR( ; b < pred_real_bands_yaw[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] );
+ }
+ FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS );
+ set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS );
+ hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */
+ move32();
+ }
+ }
+ FOR( b = 0; b < d_bands_yaw[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 );
+ }
+ FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ hMd->gd_fx = 0;
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) )
+ {
+ FOR( b = 0; b < bands_pitch[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 );
+ }
+ FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ hMd->gd_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */
+ move32();
+ hMd->gd2_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 );
+ }
+ FOR( ; b < pred_real_bands_roll[quant_strat]; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 );
+ }
+ FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
+ {
+ hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS );
+ set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS );
+ hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */
+ move32();
+ }
+ }
+ }
+ }
+ }
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ float val;
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW )
+ {
+ for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ if ( fabsf( hMd->gd_idx - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ for ( b = 0; b < bands_pitch[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ if ( fabsf( hMd->gd_idx - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx;
+ if ( fabsf( hMd->gd2_idx - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ else
+ {
+ for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 )
+ {
+ assert( 0 );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function wrap_around_angle()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void wrap_around_angle_fx(
+ Word32 *a_fx )
+{
+ IF( GT_32( ( *a_fx ), 754974720 /*180.f in Q22*/ ) )
+ {
+ *a_fx = L_sub( ( *a_fx ), 1509949440 /*360.f in Q22*/ );
+ }
+ ELSE IF( LT_32( ( *a_fx ), L_negate( 754974720 /*180.f in Q22*/ ) ) )
+ {
+ *a_fx = L_add( *a_fx, 1509949440 /*360.f in Q22*/ );
+ }
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function wrap_around_angle()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void wrap_around_ypr_fx(
+ IVAS_QUATERNION *Quaternions )
+{
+ /*only if quat is actually yaw, pitch , roll angles*/
+ IF( EQ_32( Quaternions->w_fx, L_negate( 12582912 /*3.0f in Q22*/ ) ) )
+ {
+ wrap_around_angle_fx( &Quaternions->x_fx );
+ wrap_around_angle_fx( &Quaternions->y_fx );
+ wrap_around_angle_fx( &Quaternions->z_fx );
+ }
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function wrap_around_angle()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static Word32 get_interp_fact_fx(
+ Word32 p_fx[MAX_HEAD_ROT_POSES],
+ const Word32 p_t_fx,
+ const Word16 ind[2],
+ Word16 *exp )
+{
+ Word32 n_fx, d_fx, interp_fact_fx;
+ *exp = 31;
+ move16();
+ IF( NE_16( ind[0], ind[1] ) )
+ {
+ n_fx = L_sub( p_fx[ind[0]], p_fx[ind[1]] );
+ move32();
+ d_fx = L_sub( p_fx[ind[0]], p_t_fx );
+ move32();
+ interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp
+ move32();
+ IF( LT_32( interp_fact_fx, 0 ) )
+ {
+ d_fx = max( -( MAX_EXTRAPOLATION_ANGLE_Q22 ), ( min( ( MAX_EXTRAPOLATION_ANGLE_Q22 ), d_fx ) ) );
+ move32();
+ n_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( n_fx, Q31_BY_360 ), 7 ) ) ) );
+ move32();
+ d_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( d_fx, Q31_BY_360 ), 7 ) ) ) );
+ move32();
+ interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp
+ move32();
+ }
+ }
+ ELSE
+ {
+ interp_fact_fx = 0;
+ move32();
+ }
+ return interp_fact_fx;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function get_nearest_pose_ind()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void get_nearest_pose_ind_fx(
+ Word32 p[MAX_HEAD_ROT_POSES],
+ const Word32 p_t,
+ Word16 ind[2],
+ const Word16 num_poses )
+{
+ Word32 min_diff, diff;
+ Word16 pos_idx;
+
+ ind[0] = 0;
+ ind[1] = 0;
+ min_diff = 1509949440; // 360 in Q22
+
+ /*find the closest pose from assumed poses*/
+ FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+ diff = L_abs( L_sub( p_t, p[pos_idx] ) );
+ IF( LT_32( diff, min_diff ) )
+ {
+ ind[0] = pos_idx;
+ min_diff = diff;
+ }
+ }
+
+ min_diff = 1509949440; // 360 in Q22
+ FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+ diff = L_abs( L_sub( p_t, p[pos_idx] ) );
+ IF( LT_32( diff, min_diff ) &&
+ GT_32( L_abs( L_sub( p[pos_idx], p[ind[0]] ) ), EPSILON_FX ) )
+ {
+ ind[1] = pos_idx;
+ min_diff = diff;
+ }
+ }
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function get_interpolation_vars()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void get_interpolation_vars(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const IVAS_QUATERNION *Quaternions_ref,
+ const IVAS_QUATERNION *Quaternions_act,
+ int16_t interp_yaw_pose_idx[2],
+ int16_t interp_pitch_pose_idx[2],
+ int16_t interp_roll_pose_idx[2],
+ Word32 *interp_yaw_fact_fx,
+ Word32 *interp_pitch_fact_fx,
+ Word32 *interp_roll_fact_fx,
+ Word16 *q_yaw,
+ Word16 *q_pitch,
+ Word16 *q_roll )
+{
+ IVAS_QUATERNION quaternions_diff, quaternions_ref_euler, quaternions_act_euler;
+ Word32 y_fx[MAX_HEAD_ROT_POSES], p_fx[MAX_HEAD_ROT_POSES], r_fx[MAX_HEAD_ROT_POSES];
+
+ int16_t pos_idx, num_poses;
+ Word16 exp;
+
+ quaternions_diff.x_fx = 0;
+ quaternions_diff.y_fx = 0;
+ quaternions_diff.z_fx = 0;
+
+ num_poses = pMultiBinPoseData->num_poses;
+
+ FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+ quaternions_diff.x_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][0];
+ quaternions_diff.y_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][1];
+ quaternions_diff.z_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][2];
+ y_fx[pos_idx] = quaternions_diff.x_fx;
+ p_fx[pos_idx] = quaternions_diff.y_fx;
+ r_fx[pos_idx] = quaternions_diff.z_fx;
+ }
+
+ /*interpolation if actual pose is not same as one of assumed poses*/
+ /*get the deviation*/
+ Quat2EulerDegree_fx( *Quaternions_ref, &quaternions_ref_euler.z_fx, &quaternions_ref_euler.y_fx, &quaternions_ref_euler.x_fx ); /*order in Quat2Euler seems to be reversed ?*/
+ Quat2EulerDegree_fx( *Quaternions_act, &quaternions_act_euler.z_fx, &quaternions_act_euler.y_fx, &quaternions_act_euler.x_fx );
+
+ /*order in Quat2Euler seems to be reversed ?*/
+ quaternions_diff.w_fx = -12582912; /*euler*/ //-3 in Q22
+ quaternions_diff.x_fx = L_sub( quaternions_act_euler.x_fx, quaternions_ref_euler.x_fx );
+ quaternions_diff.y_fx = L_sub( quaternions_act_euler.y_fx, quaternions_ref_euler.y_fx );
+ quaternions_diff.z_fx = L_sub( quaternions_act_euler.z_fx, quaternions_ref_euler.z_fx );
+ wrap_around_ypr_fx( &quaternions_diff );
+ interp_yaw_pose_idx[0] = 0;
+ interp_yaw_pose_idx[1] = 0;
+ IF( GT_32( L_abs( quaternions_diff.x_fx ), EPSILON_FX ) )
+ {
+ get_nearest_pose_ind_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, num_poses );
+ }
+ *interp_yaw_fact_fx = get_interp_fact_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, &exp );
+ *q_yaw = Q31 - exp;
+
+ interp_pitch_pose_idx[0] = 0;
+ interp_pitch_pose_idx[1] = 0;
+ IF( GT_32( L_abs( quaternions_diff.y_fx ), EPSILON_FX ) )
+ {
+ get_nearest_pose_ind_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, num_poses );
+ }
+ *interp_pitch_fact_fx = get_interp_fact_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, &exp );
+ *q_pitch = Q31 - exp;
+
+ interp_roll_pose_idx[0] = 0;
+ interp_roll_pose_idx[1] = 0;
+ IF( GT_32( L_abs( quaternions_diff.z_fx ), EPSILON_FX ) )
+ {
+ get_nearest_pose_ind_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, num_poses );
+ }
+ *interp_roll_fact_fx = get_interp_fact_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, &exp );
+ *q_roll = Q31 - exp;
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function interpolate_pred_matrix()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void interpolate_pred_matrix_fx(
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
+ const Word16 sf_idx,
+ const Word16 band_idx,
+ const Word16 ind[2],
+ const Word32 interp_fact_fx,
+ Word16 intrep_norm,
+ Word32 mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_mat_re,
+ Word32 mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_mat_im )
+{
+ Word16 ch_idx1, ch_idx2;
+ ISAR_BIN_HR_SPLIT_REND_MD *pRot_md;
+ // ord16 intrep_norm = Q_factor_L(interp_fact);
+ // ord32 interp_fact_fx = floatToFixed(interp_fact, intrep_norm);
+ Word32 diff_fx;
+ Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_re2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_im2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 buff_exp_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], buff_exp_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ set32_fx( mix_mat_re1_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ set32_fx( mix_mat_im1_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ mix_mat_re1_fx[ch_idx1][ch_idx1] = ONE_IN_Q25;
+
+ set32_fx( mix_mat_re2_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ set32_fx( mix_mat_im2_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ mix_mat_re2_fx[ch_idx1][ch_idx1] = ONE_IN_Q25;
+ }
+
+ IF( ind[0] != 0 )
+ {
+ pRot_md = &rot_md[ind[0] - 1][sf_idx][band_idx];
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ )
+ {
+ mix_mat_re1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2];
+ mix_mat_im1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2];
+ }
+ }
+ }
+
+ IF( ind[1] != 0 )
+ {
+ pRot_md = &rot_md[ind[1] - 1][sf_idx][band_idx];
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ )
+ {
+ mix_mat_re2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2];
+ mix_mat_im2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2];
+ }
+ }
+ }
+
+ Word16 final_exp = 0, mat_re_exp = 0, mat_im_exp = 0;
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ )
+ {
+ final_exp = 0;
+ diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_re2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp );
+ Word64 tmp1 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm)
+ Word16 tmp1_nrm = W_norm( tmp1 );
+ Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm
+ mat_re_exp = 0;
+ mat_re_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp1_final ), final_exp + ( 31 - intrep_norm ) - tmp1_nrm, &mat_re_exp );
+ buff_exp_re[ch_idx1][ch_idx2] = mat_re_exp;
+
+ final_exp = 0;
+ diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_im2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp );
+ Word64 tmp2 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm)
+ Word16 tmp2_nrm = W_norm( tmp2 );
+ Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm
+ mat_im_exp = 0;
+ mat_im_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp2_final ), final_exp + ( 31 - intrep_norm ) - tmp2_nrm, &mat_im_exp );
+ buff_exp_im[ch_idx1][ch_idx2] = mat_im_exp;
+ }
+ }
+
+ Word16 max_exp_re = MIN16B;
+ Word16 max_exp_im = MIN16B;
+ FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ max_exp_re = max( max_exp_re, buff_exp_re[i][j] );
+ max_exp_im = max( max_exp_im, buff_exp_im[i][j] );
+ }
+ }
+ FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ mat_re_fx[i][j] = L_shr( mat_re_fx[i][j], max_exp_re - buff_exp_re[i][j] );
+ mat_im_fx[i][j] = L_shr( mat_im_fx[i][j], max_exp_im - buff_exp_im[i][j] );
+ }
+ }
+
+ *exp_mat_re = max_exp_re;
+ *exp_mat_im = max_exp_im;
+
+ return;
+}
+/*-----------------------------------------------------------------------------------------*
+ * Function interpolate_rend_md()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+static void interpolate_rend_md_fx(
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
+ Word32 mix_mat_re_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_mix_mat_re,
+ Word32 mix_mat_im_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_mix_mat_im,
+ Word32 *gd_int_fx,
+ Word16 *exp_gd_int,
+ const Word16 sf_idx,
+ const Word16 band_idx,
+ const Word16 interp_yaw_pose_idx[2],
+ const Word16 interp_pitch_pose_idx[2],
+ const Word16 interp_roll_pose_idx[2],
+ const Word32 interp_yaw_fact_fx,
+ Word16 Q_yaw,
+ const Word32 interp_pitch_fact_fx,
+ Word16 Q_pitch,
+ const Word32 interp_roll_fact_fx,
+ Word16 Q_roll )
+{
+ Word16 ch_idx1, idx1, idx2;
+
+ Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_re3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_im3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+
+ Word16 exp_mix_mat_re1 = 0;
+ Word16 exp_mix_mat_im1 = 0;
+ Word16 exp_mix_mat_re3 = 0;
+ Word16 exp_mix_mat_im3 = 0;
+
+ Word16 ch_idx2;
+ Word16 exp_pitch_gain_r, exp_pitch_gain_l;
+ Word32 gd1_fx = 0, gd2_fx = 0;
+ Word32 gd3_fx = 0, gd4_fx = 0;
+ Word32 pitch_gain_r_fx, pitch_gain_l_fx;
+ Word32 diff_fx;
+
+ Word16 exp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 exp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+
+ idx1 = interp_yaw_pose_idx[0];
+ idx2 = interp_yaw_pose_idx[1];
+
+
+ IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) )
+ {
+ interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact_fx, Q_yaw, mix_mat_re_fx, exp_mix_mat_re, mix_mat_im_fx, exp_mix_mat_im );
+
+ IF( NE_16( idx1, 0 ) )
+ {
+ gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx; // Q25
+ }
+
+ IF( NE_16( idx2, 0 ) )
+ {
+ gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx;
+ }
+ diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25
+ Word32 tmp1 = Mpy_32_32( diff_fx, interp_yaw_fact_fx ); // 6+Q_yaw
+ Word16 exp_tmp2 = 0;
+ Word32 tmp2 = BASOP_Util_Add_Mant32Exp( diff_fx, 31 - Q25, L_negate( tmp1 ), 6 + Q_yaw, &exp_tmp2 );
+ *gd_int_fx = tmp2;
+ *exp_gd_int = exp_tmp2;
+ }
+ ELSE
+ {
+ /*P = P'*/
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ mix_mat_re_fx[ch_idx1][j] = 0;
+ mix_mat_im_fx[ch_idx1][j] = 0;
+ mix_mat_re_fx[ch_idx1][ch_idx1] = ONE_IN_Q25;
+ }
+ }
+
+ *exp_mix_mat_re = 6;
+ *exp_mix_mat_im = 6;
+
+ *gd_int_fx = 0;
+ *exp_gd_int = 0;
+ }
+
+ idx1 = interp_pitch_pose_idx[0];
+ idx2 = interp_pitch_pose_idx[1];
+ IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) )
+ {
+ gd1_fx = ONE_IN_Q25;
+ gd2_fx = ONE_IN_Q25;
+
+ gd3_fx = ONE_IN_Q25;
+ gd4_fx = ONE_IN_Q25;
+
+ IF( NE_16( idx1, 0 ) )
+ {
+ gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx;
+ gd3_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd2_fx;
+ }
+ IF( NE_16( idx2, 0 ) )
+ {
+ gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx;
+ gd4_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd2_fx;
+ }
+
+ diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25
+ IF( EQ_32( diff_fx, -1 ) )
+ {
+ diff_fx = 0;
+ }
+ Word32 tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx ); // 6 + Q_pitch
+ Word16 exp_tmp1 = 0;
+ Word32 tmp1 = BASOP_Util_Add_Mant32Exp( gd1_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 );
+ pitch_gain_l_fx = tmp1;
+ pitch_gain_l_fx = max( 0, pitch_gain_l_fx );
+ exp_pitch_gain_l = exp_tmp1;
+
+ diff_fx = L_sub( gd3_fx, gd4_fx );
+ IF( EQ_32( diff_fx, -1 ) )
+ {
+ diff_fx = 0;
+ }
+ tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx );
+ exp_tmp1 = 0;
+ tmp1 = BASOP_Util_Add_Mant32Exp( gd3_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 );
+ pitch_gain_r_fx = tmp1;
+ pitch_gain_r_fx = max( 0, pitch_gain_r_fx );
+ exp_pitch_gain_r = exp_tmp1;
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ mix_mat_re_fx[ch_idx1][0] = Mpy_32_32( mix_mat_re_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_re + exp_pitch_gain_l
+ exp_mat_re[ch_idx1][0] = *exp_mix_mat_re + exp_pitch_gain_l;
+ mix_mat_re_fx[ch_idx1][1] = Mpy_32_32( mix_mat_re_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_re + exp_pitch_gain_r
+ exp_mat_re[ch_idx1][1] = *exp_mix_mat_re + exp_pitch_gain_r;
+ mix_mat_im_fx[ch_idx1][0] = Mpy_32_32( mix_mat_im_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_im + exp_pitch_gain_l
+ exp_mat_im[ch_idx1][0] = *exp_mix_mat_im + exp_pitch_gain_l;
+ mix_mat_im_fx[ch_idx1][1] = Mpy_32_32( mix_mat_im_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_im + exp_pitch_gain_r
+ exp_mat_im[ch_idx1][1] = *exp_mix_mat_im + exp_pitch_gain_r;
+ }
+
+ Word16 max_exp_re = MIN16B, max_exp_im = MIN16B;
+ FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ max_exp_re = max( max_exp_re, exp_mat_re[i][j] );
+ max_exp_im = max( max_exp_im, exp_mat_im[i][j] );
+ }
+ }
+
+ FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ mix_mat_re_fx[i][j] = L_shr( mix_mat_re_fx[i][j], max_exp_re - exp_mat_re[i][j] );
+ mix_mat_im_fx[i][j] = L_shr( mix_mat_im_fx[i][j], max_exp_im - exp_mat_im[i][j] );
+ }
+ }
+
+ *exp_mix_mat_re = max_exp_re;
+ *exp_mix_mat_im = max_exp_im;
+ }
+ ELSE
+ {
+ pitch_gain_l_fx = ONE_IN_Q25;
+ pitch_gain_r_fx = ONE_IN_Q25;
+ }
+
+
+ idx1 = interp_roll_pose_idx[0];
+ idx2 = interp_roll_pose_idx[1];
+ IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) )
+ {
+ interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact_fx, Q_roll, mix_mat_re3_fx, &exp_mix_mat_re3, mix_mat_im3_fx, &exp_mix_mat_im3 );
+
+ isar_mat_mult_2by2_complex_fx( mix_mat_re_fx, *exp_mix_mat_re, mix_mat_im_fx, *exp_mix_mat_im, mix_mat_re3_fx, exp_mix_mat_re3,
+ mix_mat_im3_fx, exp_mix_mat_im3, mix_mat_re1_fx, &exp_mix_mat_re1, mix_mat_im1_fx, &exp_mix_mat_im1 );
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ )
+ {
+ mix_mat_re_fx[ch_idx1][ch_idx2] = mix_mat_re1_fx[ch_idx1][ch_idx2];
+ mix_mat_im_fx[ch_idx1][ch_idx2] = mix_mat_im1_fx[ch_idx1][ch_idx2];
+ }
+ }
+ *exp_mix_mat_re = exp_mix_mat_re1;
+ *exp_mix_mat_im = exp_mix_mat_im1;
+ }
+
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_SplitRenderer_PostRenderer()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+void isar_SplitRenderer_PostRenderer(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
+ Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
+ const IVAS_QUATERNION Quaternion_act )
+{
+ int16_t pos_idx, b, brange[2], ch_idx1;
+ int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md;
+ Word32 pred_out_re_fx[BINAURAL_CHANNELS], pred_out_im_fx[BINAURAL_CHANNELS], tmp_re_fx, tmp_im_fx, gd_int_fx;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS];
+#else
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS];
+#endif
+ int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2];
+ Word32 interp_yaw_fact_fx, interp_pitch_fact_fx, interp_roll_fact_fx;
+ Word16 Q_yaw = Q31, Q_pitch = Q31, Q_roll = Q31;
+ Word32 mix_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mix_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ float Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+#endif
+ Word16 fade_fx;
+ Word32 *pMix_mat_re_prev_fx[BINAURAL_CHANNELS];
+ Word32 *pMix_mat_im_prev_fx[BINAURAL_CHANNELS];
+ const int16_t *pBand_grouping = isar_split_rend_band_grouping;
+
+ num_md_bands = MAX_SPLIT_REND_MD_BANDS;
+
+ push_wmops( "isar_SplitRenderer_PostRenderer" );
+
+ num_slots = MAX_PARAM_SPATIAL_SUBFRAMES;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ pos_idx = MAX_HEAD_ROT_POSES - 1;
+#else
+ pos_idx = 0;
+#endif
+
+ sf_idx_md = 0;
+
+ get_interpolation_vars( pMultiBinPoseData, &hBinPostRenderer->QuaternionsPre[sf_idx_md], &Quaternion_act, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, &interp_yaw_fact_fx, &interp_pitch_fact_fx, &interp_roll_fact_fx, &Q_yaw, &Q_pitch, &Q_roll );
+
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ set_l( mix_mat_re_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ set_l( mix_mat_im_fx[ch_idx1], 0, BINAURAL_CHANNELS );
+ mix_mat_re_fx[ch_idx1][ch_idx1] = L_shl( 1, Q25 );
+ }
+
+ Word16 exp_gd_int = 0;
+
+ Word16 exp_mix_mat_re = 6, exp_mix_mat_im = 6;
+
+ interpolate_rend_md_fx( hBinPostRenderer->rot_md, mix_mat_re_fx, &exp_mix_mat_re, mix_mat_im_fx, &exp_mix_mat_im, &gd_int_fx, &exp_gd_int, sf_idx_md, b, interp_yaw_pose_idx,
+ interp_pitch_pose_idx, interp_roll_pose_idx, interp_yaw_fact_fx, Q_yaw, interp_pitch_fact_fx, Q_pitch, interp_roll_fact_fx, Q_roll );
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ /*update the prediction matrix with interpolated matrix*/
+ rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0] = L_shl( mix_mat_re_fx[ch_idx1][0], exp_mix_mat_re - 6 ); // Q25
+ rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1] = L_shl( mix_mat_re_fx[ch_idx1][1], exp_mix_mat_re - 6 ); // Q25
+ rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0] = L_shl( mix_mat_im_fx[ch_idx1][0], exp_mix_mat_im - 6 ); // Q25
+ rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1] = L_shl( mix_mat_im_fx[ch_idx1][1], exp_mix_mat_im - 6 ); // Q25
+ rot_md_act[pos_idx][b].gd_fx = L_shl( gd_int_fx, exp_gd_int - 6 ); // Q25
+ }
+ }
+
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ )
+ {
+ for ( b = 0; b < num_md_bands; b++ )
+ {
+ if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY )
+ {
+
+ for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS );
+ set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS );
+ hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f;
+ }
+ hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd;
+ hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2;
+ hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f;
+ }
+ else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL )
+ {
+ hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f;
+ }
+
+ for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+
+ /*update the prediction matrix with interpolated matrix*/
+ rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0];
+ rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1];
+ rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0];
+ rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1];
+ rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd;
+ }
+ }
+ }
+
+#endif
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+#else
+ pos_idx = 0;
+#endif
+ {
+ FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
+ {
+ index_slot = slot_idx; /* TODO: can be cleaned up */
+ fade_fx = fade_table_fx[slot_idx];
+ fade_fx = min( fade_fx, MAX_16 );
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ IF( hBinPostRenderer->cf_flag )
+ {
+ pMix_mat_re_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1];
+ pMix_mat_im_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1];
+ mix_mat_re_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0], fade_fx ),
+ Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) );
+ mix_mat_re_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1], fade_fx ),
+ Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) );
+
+ mix_mat_im_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0], fade_fx ),
+ Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) );
+ mix_mat_im_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1], fade_fx ),
+ Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) );
+ }
+ ELSE
+ {
+ mix_mat_re_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0];
+ mix_mat_re_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1];
+ mix_mat_im_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0];
+ mix_mat_im_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1];
+ }
+ }
+
+ brange[0] = pBand_grouping[b];
+ brange[1] = pBand_grouping[b + 1];
+ Word16 exp_tmp1, exp_tmp2;
+ FOR( b2 = brange[0]; b2 < brange[1]; b2++ )
+ {
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ /* Apply prediction matrix */
+ ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, mix_mat_re_fx[0][ch_idx1], 6, mix_mat_im_fx[0][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 );
+ // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25
+ // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25
+
+ pred_out_re_fx[ch_idx1] = tmp_re_fx;
+ pred_out_im_fx[ch_idx1] = tmp_im_fx;
+ Word16 exp_re = exp_tmp1;
+ Word16 exp_im = exp_tmp2;
+
+ ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, mix_mat_re_fx[1][ch_idx1], 6, mix_mat_im_fx[1][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 );
+ // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25
+ // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25
+
+ pred_out_re_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_re_fx[ch_idx1], exp_re, tmp_re_fx, exp_tmp1, &exp_re );
+ pred_out_re_fx[ch_idx1] = L_shl( pred_out_re_fx[ch_idx1], exp_re - 25 );
+ pred_out_im_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_im_fx[ch_idx1], exp_im, tmp_im_fx, exp_tmp2, &exp_im );
+ pred_out_im_fx[ch_idx1] = L_shl( pred_out_im_fx[ch_idx1], exp_im - 25 );
+ }
+
+
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1];
+ Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1];
+#else
+ Cldfb_RealBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_re_fx[ch_idx1];
+ Cldfb_ImagBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_im_fx[ch_idx1];
+#endif
+ }
+ }
+ }
+ }
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+#else
+ pos_idx = 0;
+#endif
+ {
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0]; // Q25
+ hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1]; // Q25
+ hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0]; // Q25
+ hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1]; // Q25
+ }
+ hBinPostRenderer->gd_mem_fx[pos_idx][b] = rot_md_act[pos_idx][b].gd_fx; // Q25
+ }
+ }
+ hBinPostRenderer->cf_flag = 1;
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ {
+ int16_t num_cldfb_bands;
+ num_cldfb_bands = CLDFB_NO_CHANNELS_MAX;
+ for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
+ {
+ index_slot = sf_idx * num_slots + slot_idx;
+ for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
+ {
+ mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands );
+ mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands );
+ }
+ }
+
+ for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ char fname[200] = "recons_out_pos";
+ char tag[2];
+ tag[0] = (char) ( '0' + pos_idx );
+ tag[1] = '\0';
+ strcat( fname, tag );
+ strcat( fname, ".wav" );
+ isar_log_cldfb2wav_data(
+ Cldfb_RealBuffer_Recons_Binaural[pos_idx],
+ Cldfb_ImagBuffer_Recons_Binaural[pos_idx],
+ hBinPostRenderer->cldfbSynReconsBinDec[pos_idx],
+ BINAURAL_CHANNELS,
+ num_cldfb_bands,
+ 48000,
+ num_slots,
+ sf_idx * num_slots,
+ fname );
+ }
+ }
+#endif
+
+ pop_wmops();
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_rend_CldfbSplitPostRendProcessTdIn()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+static void isar_rend_CldfbSplitPostRendProcessTdIn(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const IVAS_QUATERNION QuaternionPost,
+ Word32 output_fx[][L_FRAME48k],
+ Word16 *Q_out )
+{
+ int16_t ch_idx, slot_idx, num_cldfb_bands;
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 };
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 };
+ num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels;
+ Word16 Q_output = 11;
+
+ /* Implement CLDFB analysis */
+ FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
+ {
+ Scale_sig32( output_fx[ch_idx], L_FRAME48k, Q_output - Q_out[ch_idx] );
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ Word16 Q_cldfb = Q_output;
+ cldfbAnalysis_ts_fx_fixed_q( &( output_fx[ch_idx][num_cldfb_bands * slot_idx] ),
+ Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx],
+ Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx],
+ num_cldfb_bands,
+ hBinHrSplitPostRend->cldfbAna[ch_idx],
+ &Q_cldfb ); // Q_cldfb - 5
+ }
+ }
+
+ isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost );
+
+ /* Implement CLDFB synthesis */
+ FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
+ {
+ Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word16 scaleFactor = 31, Q_cldfb;
+
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx];
+ ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx];
+ scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) );
+ }
+
+ scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ }
+ Q_cldfb = add( scaleFactor, sub( Q_output, Q5 ) );
+ Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) );
+ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1
+ Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) );
+ Q_out[ch_idx] = sub( Q_cldfb, 1 );
+ }
+
+ return;
+}
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_rend_CldfbSplitPostRendProcess()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+void isar_rend_CldfbSplitPostRendProcess(
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const IVAS_QUATERNION QuaternionPost,
+ Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ Word16 Q_cldfb_in,
+ Word32 output_fx[][L_FRAME48k],
+ Word16 *Q_out,
+ const Word16 cldfb_in_flag )
+{
+ int16_t ch_idx, slot_idx, num_cldfb_bands;
+
+ push_wmops( "isar_rend_CldfbSplitPostRendProcess" );
+
+ num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels;
+
+ IF( EQ_16( cldfb_in_flag, 0 ) )
+ {
+ isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output_fx, Q_out );
+ pop_wmops();
+ return;
+ }
+
+ isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost );
+
+ /* Implement CLDFB synthesis */
+ FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
+ {
+ Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word16 scaleFactor = 31, Q_cldfb;
+
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx];
+ ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx];
+ scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) );
+ }
+
+ scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ }
+ Q_cldfb = scaleFactor + Q_cldfb_in;
+ Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) );
+ cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1
+ Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) );
+ Q_out[ch_idx] = sub( Q_cldfb, 1 );
+ }
+
+ pop_wmops();
+ return;
+}
+
+/*-----------------------------------------------------------------------------------------*
+ * Function isar_init_split_post_rend_handles()
+ *
+ *
+ *-----------------------------------------------------------------------------------------*/
+
+void isar_init_split_post_rend_handles(
+ ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper )
+{
+ hSplitRendWrapper->hBinHrSplitPostRend = NULL;
+ hSplitRendWrapper->hSplitBinLCLDDec = NULL;
+ hSplitRendWrapper->hLc3plusDec = NULL;
+ isar_init_multi_bin_pose_data_fx( &hSplitRendWrapper->multiBinPoseData );
+ hSplitRendWrapper->first_good_frame_received = 0;
+
+ return;
+}
+
+#endif
diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e2e19ac433a0d201c3c91cf833d8c536073dc9c
--- /dev/null
+++ b/lib_isar/isar_splitRendererPre.c
@@ -0,0 +1,3469 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+#include
+#endif
+#include "ivas_prot.h"
+#include "prot.h"
+#include "lib_isar_pre_rend.h"
+#include "isar_rom_post_rend.h"
+#include "isar_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+#ifdef DBG_WAV_WRITER
+#include "string.h"
+#endif
+#include "prot_fx2.h"
+#include "basop_util.h"
+
+/*---------------------------------------------------------------------*
+ * Local function declarations
+ *---------------------------------------------------------------------*/
+static void isar_SplitRenderer_GetRotMd_fx(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
+ Word16 exp_cldfb_re,
+ Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
+ Word16 exp_cldfb_im,
+ const Word16 low_res,
+ const Word16 ro_md_flag );
+
+/*-------------------------------------------------------------------------
+ * Local functions
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static void isar_calc_mat_det_2by2_complex_fx(
+ Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_re,
+ Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_im,
+ Word32 *det_re,
+ Word16 *exp_det_re,
+ Word32 *det_im,
+ Word16 *exp_det_im )
+{
+ Word32 re1_fx, im1_fx, re2_fx, im2_fx;
+
+ Word16 exp_re_1 = 0, exp_re_2 = 0;
+ Word16 exp_im_1 = 0, exp_im_2 = 0;
+ ivas_cmult_fix( in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re1_fx, &im1_fx, &exp_re_1, &exp_im_1 );
+ ivas_cmult_fix( in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re2_fx, &im2_fx, &exp_re_2, &exp_im_2 );
+
+ Word16 exp_re_final = 0, exp_im_final = 0;
+ *det_re = BASOP_Util_Add_Mant32Exp( re1_fx, exp_re_1, L_negate( re2_fx ), exp_re_2, &exp_re_final );
+ *det_im = BASOP_Util_Add_Mant32Exp( im1_fx, exp_im_1, L_negate( im2_fx ), exp_im_2, &exp_im_final );
+ *exp_det_re = exp_re_final;
+ *exp_det_im = exp_im_final;
+
+ return;
+}
+
+static Word16 isar_is_mat_inv_2by2_complex_fx(
+ Word32 in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_re,
+ Word32 in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_im )
+{
+ Word16 is_det_zero = 1;
+ Word32 det, det_re, det_im;
+ Word16 exp_det = 0, exp_det_re = 0, exp_det_im = 0;
+ isar_calc_mat_det_2by2_complex_fx( in_re, exp_in_re, in_im, exp_in_im, &det_re, &exp_det_re, &det_im, &exp_det_im );
+
+ Word64 det_re_sq = W_mult_32_32( det_re, det_re );
+ Word16 det_sq_re_nrm = W_norm( det_re_sq );
+ Word32 tmp1 = W_extract_h( W_shl( det_re_sq, det_sq_re_nrm ) );
+
+ Word64 det_im_sq = W_mult_32_32( det_im, det_im );
+ Word16 det_im_nrm = W_norm( det_im_sq );
+ Word32 tmp2 = W_extract_h( W_shl( det_im_sq, det_im_nrm ) );
+
+ det = BASOP_Util_Add_Mant32Exp( tmp1, exp_det_re + exp_det_re - det_sq_re_nrm, tmp2, exp_det_im + exp_det_im - det_im_nrm, &exp_det );
+
+ Word16 res = BASOP_Util_Cmp_Mant32Exp( det, exp_det, EPSILON_FX, 31 );
+ IF( EQ_16( res, -1 ) )
+ {
+ is_det_zero = 0;
+ }
+
+ return is_det_zero;
+}
+static void isar_calc_mat_inv_2by2_complex_fx(
+ Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_re,
+ Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 exp_in_im,
+ Word32 out_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_out_re,
+ Word32 out_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_out_im )
+{
+ Word16 exp_buffer_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buffer_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ exp_buffer_re[i][j] = MIN16B;
+ move16();
+ exp_buffer_im[i][j] = MIN16B;
+ move16();
+ }
+ }
+ Word32 det_re_fx, det_im_fx;
+ Word16 exp_det_re = 0, exp_det_im = 0;
+ move16();
+ move16();
+ Word32 re_fx, im_fx, det_fx;
+ Word16 exp_re = 0, exp_im = 0;
+ move16();
+ move16();
+
+ isar_calc_mat_det_2by2_complex_fx( in_re_fx, exp_in_re, in_im_fx, exp_in_im, &det_re_fx, &exp_det_re, &det_im_fx, &exp_det_im );
+
+ Word16 tmp1 = W_norm( W_mult_32_32( det_re_fx, det_re_fx ) );
+ Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( det_re_fx, det_re_fx ), tmp1 ) ); // 2*exp_det_re - tmp1
+ Word16 tmp3 = W_norm( W_mult_32_32( det_im_fx, det_im_fx ) );
+ Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( det_im_fx, det_im_fx ), tmp3 ) ); // 2*exp_im_re - tmp3
+ Word16 exp_det = 0;
+ det_fx = BASOP_Util_Add_Mant32Exp( tmp2, 2 * exp_det_re - tmp1, tmp4, 2 * exp_det_im - tmp3, &exp_det );
+
+ Word16 exp_tmp5 = 0;
+ Word16 tmp5 = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, det_fx, &exp_tmp5 );
+ exp_det = add( exp_tmp5, sub( 1, exp_det ) );
+ det_fx = L_deposit_h( tmp5 );
+
+#ifdef DEBUGGING
+ /* assert to catch cases when input is singular matrix */
+ assert( GT_32( det_fx, 0 ) );
+#endif
+
+ exp_re = 0;
+ exp_im = 0;
+ move16();
+ move16();
+ ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
+
+ Word64 tmp7 = W_mult_32_32( re_fx, det_fx );
+ Word16 tmp7_nrm = W_norm( tmp7 );
+ out_re_fx[0][0] = W_extract_h( W_shl( tmp7, tmp7_nrm ) ); // exp_re + exp_det - tmp7_nrm
+ move32();
+ Word64 tmp8 = W_mult_32_32( im_fx, det_fx );
+ Word16 tmp8_nrm = W_norm( tmp8 );
+ out_im_fx[0][0] = W_extract_h( W_shl( tmp8, tmp8_nrm ) ); // exp_im + exp_det - tmp8_nrm
+ move32();
+
+ exp_buffer_re[0][0] = add( exp_re, sub( exp_det, tmp7_nrm ) );
+ move16();
+ exp_buffer_im[0][0] = add( exp_im, sub( exp_det, tmp8_nrm ) );
+ move16();
+
+ ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
+
+ Word64 tmp9 = W_mult_32_32( L_negate( re_fx ), det_fx );
+ Word16 tmp9_nrm = W_norm( tmp9 );
+ out_re_fx[0][1] = W_extract_h( W_shl( tmp9, tmp9_nrm ) );
+ Word64 tmp10 = W_mult_32_32( L_negate( im_fx ), det_fx );
+ Word16 tmp10_nrm = W_norm( tmp10 );
+ out_im_fx[0][1] = W_extract_h( W_shl( tmp10, tmp10_nrm ) );
+
+ exp_buffer_re[0][1] = add( exp_re, sub( exp_det, tmp9_nrm ) );
+ exp_buffer_im[0][1] = add( exp_im, sub( exp_det, tmp10_nrm ) );
+
+ ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
+
+
+ Word64 tmp11 = W_mult_32_32( L_negate( re_fx ), det_fx );
+ Word16 tmp11_nrm = W_norm( tmp11 );
+ out_re_fx[1][0] = W_extract_h( W_shl( tmp11, tmp11_nrm ) );
+ Word64 tmp12 = W_mult_32_32( L_negate( im_fx ), det_fx );
+ Word16 tmp12_nrm = W_norm( tmp12 );
+ out_im_fx[1][0] = W_extract_h( W_shl( tmp12, tmp12_nrm ) );
+
+ exp_buffer_re[1][0] = add( exp_re, sub( exp_det, tmp11_nrm ) );
+ move16();
+ exp_buffer_im[1][0] = add( exp_im, sub( exp_det, tmp12_nrm ) );
+ move16();
+
+ ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im );
+
+ Word64 tmp13 = W_mult_32_32( re_fx, det_fx );
+ Word16 tmp13_nrm = W_norm( tmp13 );
+ out_re_fx[1][1] = W_extract_h( W_shl( tmp13, tmp13_nrm ) );
+ move32();
+
+ Word64 tmp14 = W_mult_32_32( im_fx, det_fx );
+ Word16 tmp14_nrm = W_norm( tmp14 );
+ out_im_fx[1][1] = W_extract_h( W_shl( tmp14, tmp14_nrm ) );
+ move32();
+
+ exp_buffer_re[1][1] = add( exp_re, sub( exp_det, tmp13_nrm ) );
+ move16();
+ exp_buffer_im[1][1] = add( exp_im, sub( exp_det, tmp14_nrm ) );
+ move16();
+
+ Word16 max_exp_re = MIN16B, max_exp_im = MIN16B;
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ max_exp_re = s_max( max_exp_re, exp_buffer_re[i][j] );
+ max_exp_im = s_max( max_exp_im, exp_buffer_im[i][j] );
+ }
+ }
+
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ out_re_fx[i][j] = L_shr( out_re_fx[i][j], max_exp_re - exp_buffer_re[i][j] );
+ move32();
+ out_im_fx[i][j] = L_shr( out_im_fx[i][j], max_exp_im - exp_buffer_im[i][j] );
+ move32();
+ }
+ }
+
+ *exp_out_re = max_exp_re;
+ move16();
+ *exp_out_im = max_exp_im;
+ move16();
+
+ return;
+}
+static void ComputePredMat_fx(
+ Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_re,
+ Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_im,
+ Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_re,
+ Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_im,
+ Word32 pred_mat_re_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_pred_mat_re,
+ Word32 pred_mat_im_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_pred_mat_im,
+ const Word16 num_chs,
+ const Word16 real_only )
+{
+ Word32 cov_ii_local_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_ii_inv_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_ii_inv_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 exp_cov_ii_local_re = 0, exp_cov_ii_inv_re = 0, exp_cov_ii_inv_im = 0;
+ Word32 trace_cov_fx;
+
+ Word16 i, j;
+
+ trace_cov_fx = 0;
+ Word16 exp_trace_cov = 0;
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ trace_cov_fx = L_add( trace_cov_fx, L_shr( cov_ii_re_fx[i][i], 1 ) );
+ }
+ exp_trace_cov = add( exp_cov_ii_re, 1 );
+
+ trace_cov_fx = L_max( 0, trace_cov_fx );
+ Word16 flag = BASOP_Util_Cmp_Mant32Exp( trace_cov_fx, exp_cov_ii_re, EPSILON_FX, 0 );
+ IF( EQ_16( flag, negate( 1 ) ) )
+ {
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ /* protection from cases when variance of ref channels is very small */
+ set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS );
+ set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
+ }
+ return;
+ }
+
+ Word16 buff_exp[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ buff_exp[i][j] = 0;
+ move16();
+ }
+ }
+
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ Copy32( cov_ii_re_fx[i], cov_ii_local_re_fx[i], num_chs );
+ set16_fx( buff_exp[i], exp_cov_ii_re, num_chs );
+ }
+
+ Word32 tmp = 0;
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ tmp = Mpy_32_32( trace_cov_fx, 214748 ); // exp_trace_cov
+ Word16 exp_tmp = 0;
+ cov_ii_local_re_fx[i][i] = BASOP_Util_Add_Mant32Exp( cov_ii_re_fx[i][i], exp_cov_ii_re, tmp, exp_trace_cov, &exp_tmp );
+ move32();
+ buff_exp[i][i] = exp_tmp;
+ move16();
+ }
+
+ Word16 max_exp = MIN16B;
+ FOR( i = 0; i < 2; i++ )
+ {
+ FOR( j = 0; j < 2; j++ )
+ {
+ max_exp = max( max_exp, buff_exp[i][j] );
+ }
+ }
+
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ FOR( j = 0; j < num_chs; j++ )
+ {
+ cov_ii_local_re_fx[i][j] = L_shr( cov_ii_local_re_fx[i][j], max_exp - buff_exp[i][j] );
+ move32();
+ }
+ }
+
+ exp_cov_ii_local_re = max_exp;
+ move16();
+
+ IF( isar_is_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im ) )
+ {
+ isar_calc_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im, cov_ii_inv_re_fx, &exp_cov_ii_inv_re, cov_ii_inv_im_fx, &exp_cov_ii_inv_im );
+ isar_mat_mult_2by2_complex_fx( cov_ii_inv_re_fx, exp_cov_ii_inv_re, cov_ii_inv_im_fx, exp_cov_ii_inv_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im );
+ }
+ ELSE
+ {
+ Word16 max_var_idx;
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS );
+ set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
+ }
+
+ max_var_idx = 0;
+ move16();
+ IF( GT_32( cov_ii_local_re_fx[1][1], cov_ii_local_re_fx[0][0] ) )
+ {
+ max_var_idx = 1;
+ }
+
+ Word16 tmp1 = 0, exp_tmp1 = 0;
+ move16();
+ move16();
+ Word16 tmp2 = 0, exp_tmp2 = 0;
+ move16();
+ move16();
+ Word16 flag1 = BASOP_Util_Cmp_Mant32Exp( cov_ii_local_re_fx[max_var_idx][max_var_idx], exp_cov_ii_local_re, EPSILON_FX, 0 );
+ IF( EQ_16( flag1, 1 ) )
+ {
+ Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ set16_fx( pred_mat_buf_re[i], *exp_pred_mat_re, BINAURAL_CHANNELS );
+ set16_fx( pred_mat_buf_im[i], *exp_pred_mat_im, BINAURAL_CHANNELS );
+ }
+ FOR( j = 0; j < num_chs; j++ )
+ {
+ tmp1 = BASOP_Util_Divide3232_Scale( cov_io_re_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp1 );
+ exp_tmp1 = exp_tmp1 + ( exp_cov_io_re - exp_cov_ii_local_re );
+ tmp2 = BASOP_Util_Divide3232_Scale( cov_io_im_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp2 );
+ exp_tmp2 = exp_tmp2 + ( exp_cov_io_im - exp_cov_ii_local_re );
+ pred_mat_re_fx[max_var_idx][j] = tmp1;
+ move32();
+ pred_mat_im_fx[max_var_idx][j] = tmp2;
+ move32();
+ pred_mat_buf_re[max_var_idx][j] = exp_tmp1;
+ move16();
+ pred_mat_buf_im[max_var_idx][j] = exp_tmp2;
+ move16();
+ }
+
+ Word16 max_re = MIN16B, max_im = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+
+ max_re = s_max( max_re, pred_mat_buf_re[i][j] );
+ move16();
+ max_im = s_max( max_im, pred_mat_buf_im[i][j] );
+ move16();
+ }
+ }
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+
+ pred_mat_re_fx[i][j] = L_shr( pred_mat_re_fx[i][j], max_re - pred_mat_buf_re[i][j] );
+ move32();
+ pred_mat_im_fx[i][j] = L_shr( pred_mat_im_fx[i][j], max_im - pred_mat_buf_im[i][j] );
+ move32();
+ }
+ }
+
+ *exp_pred_mat_re = max_re;
+ move16();
+ *exp_pred_mat_im = max_im;
+ move16();
+ }
+ }
+
+ IF( real_only )
+ {
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
+ }
+ }
+
+ return;
+}
+static void ComputePostPredCov_fx(
+ Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_re,
+ Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_im,
+ Word32 pred_mat_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_pred_mat_re,
+ Word32 pred_mat_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_pred_mat_im,
+ Word32 postpred_cov_re_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_postpred_cov_re,
+ Word16 num_chs )
+{
+ Word16 i, j;
+ Word32 dmx_mat_conj_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 dmx_mat_conj_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 temp_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 temp_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 postpred_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 exp_postpred_cov_im = 0;
+ Word16 exp_temp_mat_re = 0, exp_temp_mat_im = 0;
+
+ assert( num_chs == BINAURAL_CHANNELS );
+
+ FOR( i = 0; i < num_chs; i++ )
+ {
+ FOR( j = 0; j < num_chs; j++ )
+ {
+ dmx_mat_conj_re_fx[i][j] = pred_mat_re_fx[j][i];
+ move32();
+ dmx_mat_conj_im_fx[i][j] = L_negate( pred_mat_im_fx[j][i] );
+ move32();
+
+ temp_mat_re_fx[i][j] = pred_mat_re_fx[i][j];
+ move32();
+ temp_mat_im_fx[i][j] = pred_mat_im_fx[i][j];
+ move32();
+ }
+ set32_fx( postpred_cov_re_fx[i], 0, BINAURAL_CHANNELS );
+ }
+ isar_mat_mult_2by2_complex_fx( dmx_mat_conj_re_fx, exp_pred_mat_re, dmx_mat_conj_im_fx, exp_pred_mat_im, cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, temp_mat_re_fx, &exp_temp_mat_re, temp_mat_im_fx, &exp_temp_mat_im );
+ isar_mat_mult_2by2_complex_fx( temp_mat_re_fx, exp_temp_mat_re, temp_mat_im_fx, exp_temp_mat_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im, postpred_cov_re_fx, exp_postpred_cov_re, postpred_cov_im_fx, &exp_postpred_cov_im );
+
+ /* 2x2 mult */
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < i; j++ )
+ {
+ postpred_cov_re_fx[i][j] = postpred_cov_re_fx[j][i];
+ move32();
+ }
+ }
+
+ return;
+}
+static void ComputeBandedCrossCov_fx(
+ Word32 Cldfb_RealBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_re_1,
+ Word32 Cldfb_ImagBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_im_1,
+ const Word16 ch_start_idx1,
+ Word32 Cldfb_RealBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_re_2,
+ Word32 Cldfb_ImagBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_im_2,
+ const Word16 ch_start_idx2,
+ Word32 out_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_out_cov_re,
+ Word32 out_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 *exp_out_cov_im,
+ const Word16 num_chs,
+ const Word16 *pBand_grouping,
+ const Word16 num_slots,
+ const Word16 start_slot_idx,
+ const Word16 md_band_idx,
+ const Word16 real_only )
+{
+ Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2;
+ Word16 brange[2];
+
+ FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
+ {
+ set_l( out_cov_re_fx[ch_idx1], 0, num_chs );
+ set_l( out_cov_im_fx[ch_idx1], 0, num_chs );
+ }
+
+ brange[0] = pBand_grouping[md_band_idx];
+ move16();
+ brange[1] = pBand_grouping[md_band_idx + 1];
+ move16();
+ Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ )
+ {
+ Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2], tmp_b = out_cov_im_fx[ch_idx1][ch_idx2];
+ Word16 exp_tmp_a = 0, exp_tmp_b = 0;
+ IF( EQ_16( real_only, 0 ) )
+ {
+ FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
+ {
+ FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
+ {
+ Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp1_nrm = W_norm( tmp1 );
+ Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) );
+
+ Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp2_nrm = W_norm( tmp2 );
+ Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) );
+
+ Word16 exp_tmp3 = 0;
+ Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 );
+ Word16 exp_tmp_a_tmp = 0;
+ tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
+ exp_tmp_a = exp_tmp_a_tmp;
+
+ Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp4_nrm = W_norm( tmp4 );
+ Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm
+
+ Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp5_nrm = W_norm( tmp5 );
+ Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm
+
+ Word16 exp_tmp6 = 0;
+ Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm, &exp_tmp6 );
+ Word16 exp_tmp_b_tmp = 0;
+ tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp );
+ exp_tmp_b = exp_tmp_b_tmp;
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
+ {
+ FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
+ {
+ Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp1_nrm = W_norm( tmp1 );
+ Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) );
+
+ Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp2_nrm = W_norm( tmp2 );
+ Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) );
+
+ Word16 exp_tmp3 = 0;
+ Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 );
+ Word16 exp_tmp_a_tmp = 0;
+ tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
+ exp_tmp_a = exp_tmp_a_tmp;
+
+ tmp_b = 0;
+ exp_tmp_b = 0;
+ }
+ }
+ }
+ out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a;
+ move32();
+ out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b;
+ move32();
+ exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a;
+ move32();
+ exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b;
+ move32();
+ }
+ }
+ /*make common exponent*/
+ Word16 max_cov_re = 0, max_cov_im = 0;
+ FOR( int i = 0; i < num_chs; i++ )
+ {
+ FOR( int j = 0; j < num_chs; j++ )
+ {
+ max_cov_re = max( max_cov_re, exp_buff_re[i][j] );
+ max_cov_im = max( max_cov_im, exp_buff_im[i][j] );
+ }
+ }
+ FOR( int i = 0; i < num_chs; i++ )
+ {
+ FOR( int j = 0; j < num_chs; j++ )
+ {
+ out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], max_cov_re - exp_buff_re[i][j] );
+ move32();
+ out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], max_cov_im - exp_buff_im[i][j] );
+ move32();
+ }
+ }
+
+ *exp_out_cov_re = max_cov_re;
+ *exp_out_cov_im = max_cov_im;
+
+ return;
+}
+static void ComputeBandedCov_fx(
+ Word32 Cldfb_RealBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_re,
+ Word32 Cldfb_ImagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_im,
+ const Word16 ch_start_idx,
+ Word32 out_cov_re_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_cov_re,
+ Word32 out_cov_im_fx[][BINAURAL_CHANNELS],
+ Word16 *exp_cov_im,
+ const Word16 num_chs,
+ const Word16 *pBand_grouping,
+ const Word16 num_slots,
+ const Word16 start_slot_idx,
+ const Word16 md_band_idx,
+ const Word16 real_only )
+{
+ Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2;
+ Word16 brange[2];
+
+ FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
+ {
+ set32_fx( out_cov_re_fx[ch_idx1], 0, num_chs );
+ set32_fx( out_cov_im_fx[ch_idx1], 0, num_chs );
+ }
+
+ brange[0] = pBand_grouping[md_band_idx];
+ move16();
+ brange[1] = pBand_grouping[md_band_idx + 1];
+ move16();
+
+ Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ exp_buff_re[i][j] = 0;
+ move16();
+ exp_buff_im[i][j] = 0;
+ move16();
+ }
+ }
+
+ FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
+ {
+ FOR( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ )
+ {
+ Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2];
+ Word32 tmp_b = out_cov_im_fx[ch_idx1][ch_idx2];
+ Word16 exp_tmp_a = 0, exp_tmp_b = 0;
+ test();
+ IF( ( NE_16( ch_idx2, ch_idx1 ) ) && ( EQ_16( real_only, 0 ) ) )
+ {
+ FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
+ {
+ FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
+ {
+ Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp1_nrm = W_norm( tmp1 );
+ Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm
+
+ Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp2_nrm = W_norm( tmp2 );
+ Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm
+
+ Word16 exp_tmp3 = 0;
+ Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 );
+ Word16 exp_tmp_a_tmp = 0;
+ tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
+ exp_tmp_a = exp_tmp_a_tmp;
+
+ Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp4_nrm = W_norm( tmp4 );
+ Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re + exp_cldfb_im - tmp4_nrm
+
+ Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp5_nrm = W_norm( tmp5 );
+ Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im + exp_cldfb_re - tmp5_nrm
+
+ Word16 exp_tmp6 = 0;
+ Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re + exp_cldfb_im - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im + exp_cldfb_re - tmp5_nrm, &exp_tmp6 );
+ Word16 exp_tmp_b_tmp = 0;
+ tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp );
+ exp_tmp_b = exp_tmp_b_tmp;
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ )
+ {
+ FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ )
+ {
+ Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp1_nrm = W_norm( tmp1 );
+ Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm
+
+ Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] );
+ Word16 tmp2_nrm = W_norm( tmp2 );
+ Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm
+
+ Word16 exp_tmp3 = 0;
+ Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 );
+
+ Word16 exp_tmp_a_tmp = 0;
+ tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp );
+ exp_tmp_a = exp_tmp_a_tmp;
+
+ tmp_b = 0;
+ exp_tmp_b = 0;
+ }
+ }
+ }
+ out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a;
+ move32();
+ exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a;
+ move32();
+
+ out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b;
+ move32();
+ exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b;
+ move32();
+ }
+ }
+
+ Word16 exp_max_re = MIN16B, exp_max_im = MIN16B;
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ exp_max_re = max( exp_max_re, exp_buff_re[i][j] );
+ exp_max_im = max( exp_max_im, exp_buff_im[i][j] );
+ }
+ }
+
+ FOR( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], exp_max_re - exp_buff_re[i][j] );
+ move32();
+ out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], exp_max_im - exp_buff_im[i][j] );
+ move32();
+ }
+ }
+
+ FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ )
+ {
+ FOR( ch_idx2 = add( ch_idx1, 1 ); ch_idx2 < num_chs; ch_idx2++ )
+ {
+ out_cov_re_fx[ch_idx1][ch_idx2] = out_cov_re_fx[ch_idx2][ch_idx1];
+ move32();
+ out_cov_im_fx[ch_idx1][ch_idx2] = L_negate( out_cov_im_fx[ch_idx2][ch_idx1] );
+ move32();
+ }
+ }
+
+ *exp_cov_re = exp_max_re;
+ *exp_cov_im = exp_max_im;
+
+ return;
+}
+static Word32 GetNormFact_fx(
+ Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_re,
+ Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_im,
+ Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_re,
+ Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_im,
+ Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_oo_re,
+ Word16 *exp_norm_fact_fx )
+{
+ Word16 i, j;
+ Word32 norm_fact_fx = 0, abs_val_fx;
+ Word16 exp_abs_val = 0, exp_norm_fact = 0;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ ivas_calculate_abs_fx( cov_ii_re_fx[i][j], exp_cov_ii_re, cov_ii_im_fx[i][j], exp_cov_ii_im, &abs_val_fx, &exp_abs_val );
+ Word16 res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
+ IF( EQ_16( res_1, negate( 1 ) ) )
+ {
+ norm_fact_fx = abs_val_fx;
+ exp_norm_fact = exp_abs_val;
+ }
+
+ ivas_calculate_abs_fx( cov_io_re_fx[i][j], exp_cov_io_re, cov_io_im_fx[i][j], exp_cov_io_im, &abs_val_fx, &exp_abs_val );
+ res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
+ IF( EQ_16( res_1, negate( 1 ) ) )
+ {
+ norm_fact_fx = abs_val_fx;
+ exp_norm_fact = exp_abs_val;
+ }
+ ivas_calculate_rabs_fx( cov_oo_re_fx[i][j], exp_cov_oo_re, &abs_val_fx, &exp_abs_val );
+ res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val );
+ IF( EQ_16( res_1, negate( 1 ) ) )
+ {
+ norm_fact_fx = abs_val_fx;
+ exp_norm_fact = exp_abs_val;
+ }
+ }
+ }
+
+ Word16 flag = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, EPSILON_FX, 0 );
+ IF( EQ_16( flag, negate( 1 ) ) )
+ {
+ norm_fact_fx = ONE_IN_Q30;
+ exp_norm_fact = 1;
+ }
+
+ Word16 exp_tmp = 0;
+ Word16 tmp = BASOP_Util_Divide3232_Scale( PCM16_TO_FLT_FAC_FX_Q15, norm_fact_fx, &exp_tmp );
+ exp_tmp = add( exp_tmp, sub( 16, exp_norm_fact ) );
+ norm_fact_fx = L_deposit_h( tmp );
+ exp_norm_fact = exp_tmp;
+
+ *exp_norm_fact_fx = exp_norm_fact;
+
+ return norm_fact_fx;
+}
+
+static void isar_split_rend_huffman_encode(
+ isar_split_rend_huffman_cfg_t *huff_cfg,
+ const Word16 in,
+ Word32 *hcode,
+ Word32 *hlen )
+{
+ Word32 min_sym_val;
+ const Word32 *codebook;
+
+ min_sym_val = huff_cfg->codebook[0];
+ move32();
+
+ codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
+ *hlen = codebook[1];
+ move32();
+ *hcode = codebook[2];
+ move32();
+
+ return;
+}
+
+static void isar_split_rend_quant_md_fx(
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
+ const ISAR_SPLIT_REND_POSE_TYPE pose_type,
+ const int16_t real_only,
+ Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS],
+ const Word32 pred_1byquantstep, // Q26
+ const Word16 Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ float fix_pos_rot_mat_flt[][BINAURAL_CHANNELS],
+ const float pred_1byquantstep_flt // Q26
+#endif
+)
+{
+ int16_t ch1, ch2;
+ int16_t gd_idx_min;
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word32 quant_val;
+#else
+ Word32 sign, quant_val;
+#endif
+#ifdef DEBUG_QUANT_MD_FX
+ float quant_val_flt;
+ Word16 tmp;
+#endif
+ if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY )
+ {
+ Word32 onebyquantstep;
+
+ onebyquantstep = pred_1byquantstep;
+#ifdef DEBUG_QUANT_MD_FX
+ float onebyquantstep_flt = pred_1byquantstep_flt;
+#endif
+ IF( real_only == 1 )
+ {
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ hMd->pred_mat_re_fx[ch1][ch1] = hMd->pred_mat_re2[ch1];
+ }
+ hMd->pred_mat_re_fx[1][0] = 0;
+ hMd->pred_mat_re_fx[0][1] = 0;
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ quant_val = L_sub( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, sub( Q31, Q_frame ) ) );
+ quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0
+ }
+ }
+#else
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sign = GE_32( hMd->pred_mat_re_fx[ch1][ch2], 0 ) ? 1 : -1;
+ Word16 exp_out;
+ ivas_calculate_abs_fx( hMd->pred_mat_re_fx[ch1][ch2], Q31 - Q_frame, hMd->pred_mat_im_fx[ch1][ch2], Q31 - Q_frame, &hMd->pred_mat_re_fx[ch1][ch2], &exp_out );
+ hMd->pred_mat_re_fx[ch1][ch2] = L_shr_r( hMd->pred_mat_re_fx[ch1][ch2], sub( sub( Q31, Q_frame ), exp_out ) ); // Q_frame
+ hMd->pred_mat_re_fx[ch1][ch2] = (Word32) W_mult0_32_32( hMd->pred_mat_re_fx[ch1][ch2], sign );
+ hMd->pred_mat_im_fx[ch1][ch2] = 0;
+ }
+ }
+#endif
+ }
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ else
+ {
+#endif
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ quant_val = L_sub( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( fix_pos_rot_mat[ch1][ch2], sub( Q31, Q_frame ) ) );
+ quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
+ hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0
+
+#ifdef DEBUG_QUANT_MD_FX
+ quant_val_flt = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat_flt[ch1][ch2];
+ quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val_flt, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
+ tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt );
+ if ( hMd->pred_mat_re_idx[ch1][ch2] != tmp )
+ {
+ printf( "\nUNEQUAL INDEX\n" );
+ }
+#endif
+ }
+ }
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ }
+#endif
+
+ if ( real_only == 0 )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( hMd->pred_mat_im_fx[ch1][ch2], L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) );
+ hMd->pred_mat_im_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) );
+ // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP;
+
+
+#ifdef DEBUG_QUANT_MD_FX
+ quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) );
+ tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt );
+ if ( hMd->pred_mat_im_idx[ch1][ch2] != tmp )
+ {
+ printf( "\nUNEQUAL INDEX\n" );
+ }
+#endif
+ }
+ }
+ }
+ }
+ else if ( pose_type == COM_GAIN_ONLY )
+ {
+ quant_val = L_min( L_shl_r( 1, Q_frame ) /*ISAR_SPLIT_REND_D_MAX_VAL_FX*/, L_max( hMd->gd_fx, ISAR_SPLIT_REND_D_MIN_VAL_FX ) ); //_frame
+ gd_idx_min = 0; //(int16_t)roundf(ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL)
+ hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_D_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
+ hMd->gd_fx = W_extract_l( W_shr( W_mult0_32_32( hMd->gd_idx, ISAR_SPLIT_REND_D_Q_STEP_Q31 ), sub( Q31, Q_frame ) ) );
+ hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min );
+
+#ifdef DEBUG_QUANT_MD_FX
+ quant_val_flt = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) );
+ gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL );
+ tmp = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val_flt );
+ tmp = tmp - gd_idx_min;
+ if ( hMd->gd_idx != tmp )
+ {
+ printf( "\nUNEQUAL INDEX\n" );
+ }
+#endif
+ }
+ else if ( pose_type == LR_GAIN_ONLY )
+ {
+ quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25
+ gd_idx_min = 7; // (int16_t)roundf(ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL)
+ hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
+ hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min );
+
+#ifdef DEBUG_QUANT_MD_FX
+ quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PRED_MAX_VAL ) );
+ gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL );
+ tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt );
+ tmp = tmp - gd_idx_min;
+ if ( hMd->gd_idx != tmp )
+ {
+ printf( "\nUNEQUAL INDEX\n" );
+ }
+#endif
+ quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd2_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25
+ hMd->gd2_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) );
+ hMd->gd2_idx = sub( hMd->gd2_idx, gd_idx_min );
+
+#ifdef DEBUG_QUANT_MD_FX
+ quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PRED_MAX_VAL ) );
+ tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt );
+ tmp = tmp - gd_idx_min;
+ if ( hMd->gd2_idx != tmp )
+ {
+ printf( "\nUNEQUAL INDEX\n" );
+ }
+#endif
+ }
+ return;
+}
+
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+static void get_lr_gains( Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
+ const Word16 exp_cov_ii_re,
+ Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
+ const Word16 exp_cov_oo_re,
+ Word32 gains_fx[BINAURAL_CHANNELS],
+ Word16 *exp_gains_fx )
+{
+ Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 };
+ Word16 exp_gd_tmp = 0, i;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ gains_fx[i] = cov_ii_re_fx[i][i];
+ move32();
+ exp_gd_tmp_buf[i] = exp_cov_ii_re;
+ move16();
+
+ Word16 flag = BASOP_Util_Cmp_Mant32Exp( gains_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 );
+ IF( EQ_16( flag, negate( 1 ) ) )
+ {
+ gains_fx[i] = ONE_IN_Q25;
+ move32();
+ exp_gd_tmp_buf[i] = 6;
+ move16();
+ }
+ ELSE
+ {
+ Word16 tmp, tmp_sqrt, exp_tmp = 0;
+ tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gains_fx[i], &exp_tmp );
+ exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] );
+ tmp_sqrt = Sqrt16( tmp, &exp_tmp );
+ gains_fx[i] = L_deposit_h( tmp_sqrt );
+ move32();
+ exp_gd_tmp_buf[i] = exp_tmp;
+ move16();
+ }
+ }
+
+ Word16 max_gd_exp = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] );
+ }
+ exp_gd_tmp = max_gd_exp;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ gains_fx[i] = L_shr( gains_fx[i], max_gd_exp - exp_gd_tmp_buf[i] );
+ move32();
+ }
+
+ *exp_gains_fx = exp_gd_tmp;
+ move16();
+ return;
+}
+#endif
+
+static void ComputeCoeffs_fx(
+ Word32 cov_ii_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_re,
+ Word32 cov_ii_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_ii_im,
+ Word32 cov_io_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_re,
+ Word32 cov_io_im_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_io_im,
+ Word32 cov_oo_re_fx[][BINAURAL_CHANNELS],
+ Word16 exp_cov_oo_re,
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
+ const ISAR_SPLIT_REND_POSE_TYPE pose_type,
+ const Word16 real_only )
+{
+ Word16 i, j;
+ Word32 gd_fx, gl2_fx, gr2_fx, cov_norm_fact_fx;
+ Word16 exp_gd = 0;
+
+ Word32 postpred_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 exp_postpred_cov_re = 0;
+
+ Word32 cov_ii_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_ii_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_io_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_io_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 cov_oo_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+
+ Word16 exp_cov_ii_norm_re = 0, exp_cov_ii_norm_im = 0, exp_cov_io_norm_re = 0, exp_cov_io_norm_im = 0, exp_cov_oo_norm_re = 0;
+ Word16 exp_pred_re = 0, exp_pred_im = 0;
+
+ IF( EQ_16( pose_type, PITCH_ONLY ) )
+ {
+ Word32 gd_tmp_fx[BINAURAL_CHANNELS];
+ Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 };
+ Word16 exp_gd_tmp = 0;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ gd_tmp_fx[i] = cov_ii_re_fx[i][i];
+ move32();
+ exp_gd_tmp_buf[i] = exp_cov_ii_re;
+ move16();
+ exp_gd_tmp = exp_cov_ii_re;
+
+ Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp, EPSILON_FX, 0 );
+ IF( EQ_16( flag, negate( 1 ) ) )
+ {
+ gd_tmp_fx[i] = ONE_IN_Q25;
+ move32();
+ exp_gd_tmp_buf[i] = 6;
+ move16();
+ }
+ ELSE
+ {
+ Word16 tmp, tmp_sqrt, exp_tmp = 0;
+ tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp );
+ exp_tmp = add( exp_tmp, sub( exp_cov_oo_re, exp_gd_tmp ) );
+ tmp_sqrt = Sqrt16( tmp, &exp_tmp );
+ gd_tmp_fx[i] = L_deposit_h( tmp_sqrt );
+ move32();
+ exp_gd_tmp_buf[i] = exp_tmp;
+ move16();
+ }
+ }
+
+ Word16 max_gd_exp = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ max_gd_exp = s_max( max_gd_exp, exp_gd_tmp_buf[i] );
+ }
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ gd_tmp_fx[i] = L_shr( gd_tmp_fx[i], max_gd_exp - exp_gd_tmp_buf[i] );
+ move32();
+ }
+ exp_gd_tmp = max_gd_exp;
+ move16();
+ hMd->gd_fx = gd_tmp_fx[0];
+ move16();
+ hMd->gd2_fx = gd_tmp_fx[1];
+ move16();
+ hMd->exp_gd = exp_gd_tmp;
+ move16();
+ hMd->exp_gd2 = exp_gd_tmp;
+ move16();
+ }
+ ELSE
+ {
+ IF( real_only )
+ {
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word32 gd_tmp_fx[BINAURAL_CHANNELS];
+ get_lr_gains( cov_ii_re_fx, exp_cov_ii_re,
+ cov_oo_re_fx, exp_cov_oo_re,
+ gd_tmp_fx, &hMd->exp_pred_mat_re2 );
+ hMd->pred_mat_re_fx[1][0] = 0;
+ move32();
+ hMd->pred_mat_re_fx[0][1] = 0;
+ move32();
+ hMd->exp_pred_mat_re = hMd->exp_pred_mat_re2;
+ move16();
+ hMd->exp_pred_mat_im = hMd->exp_pred_mat_re;
+ move16();
+ for ( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i];
+ hMd->pred_mat_re2[i] = gd_tmp_fx[i];
+ set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
+ }
+
+
+#else
+ Word32 gd_tmp_fx[BINAURAL_CHANNELS];
+ Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 };
+ Word16 exp_gd_tmp = 0;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ gd_tmp_fx[i] = cov_ii_re_fx[i][i];
+ move32();
+ exp_gd_tmp_buf[i] = exp_cov_ii_re;
+ move16();
+
+ Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 );
+ IF( EQ_16( flag, negate( 1 ) ) )
+ {
+ gd_tmp_fx[i] = ONE_IN_Q25;
+ move32();
+ exp_gd_tmp_buf[i] = 6;
+ move16();
+ }
+ ELSE
+ {
+ Word16 tmp, tmp_sqrt, exp_tmp = 0;
+ tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp );
+ exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] );
+ tmp_sqrt = Sqrt16( tmp, &exp_tmp );
+ gd_tmp_fx[i] = L_deposit_h( tmp_sqrt );
+ move32();
+ exp_gd_tmp_buf[i] = exp_tmp;
+ move16();
+ }
+ hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i];
+ move32();
+ set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS );
+ }
+ hMd->pred_mat_re_fx[1][0] = 0;
+ move32();
+ hMd->pred_mat_re_fx[0][1] = 0;
+ move32();
+
+ Word16 max_gd_exp = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] );
+ }
+ exp_gd_tmp = max_gd_exp;
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ hMd->pred_mat_re_fx[i][i] = L_shr( hMd->pred_mat_re_fx[i][i], max_gd_exp - exp_gd_tmp_buf[i] );
+ move32();
+ }
+
+ exp_pred_re = exp_gd_tmp;
+ move16();
+ exp_pred_im = exp_gd_tmp;
+ move16();
+
+ hMd->exp_pred_mat_re = exp_pred_re;
+ move16();
+ hMd->exp_pred_mat_im = exp_pred_im;
+ move16();
+#endif
+ }
+ ELSE
+ {
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ get_lr_gains( cov_ii_re_fx, exp_cov_ii_re,
+ cov_oo_re_fx, exp_cov_oo_re,
+ hMd->pred_mat_re2, &hMd->exp_pred_mat_re2 );
+#endif
+ Word16 exp_norm_fact = 0;
+ cov_norm_fact_fx = GetNormFact_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &exp_norm_fact );
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ cov_ii_norm_re_fx[i][j] = Mpy_32_32( cov_ii_re_fx[i][j], cov_norm_fact_fx );
+ move32();
+ cov_ii_norm_im_fx[i][j] = Mpy_32_32( cov_ii_im_fx[i][j], cov_norm_fact_fx );
+ move32();
+ cov_io_norm_re_fx[i][j] = Mpy_32_32( cov_io_re_fx[i][j], cov_norm_fact_fx );
+ move32();
+ cov_io_norm_im_fx[i][j] = Mpy_32_32( cov_io_im_fx[i][j], cov_norm_fact_fx );
+ move32();
+ cov_oo_norm_re_fx[i][j] = Mpy_32_32( cov_oo_re_fx[i][j], cov_norm_fact_fx );
+ move32();
+ }
+ }
+
+ exp_cov_ii_norm_re = add( exp_cov_ii_re, exp_norm_fact );
+ exp_cov_ii_norm_im = add( exp_cov_ii_im, exp_norm_fact );
+ exp_cov_io_norm_re = add( exp_cov_io_re, exp_norm_fact );
+ exp_cov_io_norm_im = add( exp_cov_io_im, exp_norm_fact );
+ exp_cov_oo_norm_re = add( exp_cov_oo_re, exp_norm_fact );
+
+ ComputePredMat_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, cov_io_norm_re_fx, exp_cov_io_norm_re, cov_io_norm_im_fx, exp_cov_io_norm_im, hMd->pred_mat_re_fx, &exp_pred_re, hMd->pred_mat_im_fx, &exp_pred_im, BINAURAL_CHANNELS, real_only );
+ hMd->exp_pred_mat_re = exp_pred_re;
+ move16();
+ hMd->exp_pred_mat_im = exp_pred_im;
+ move16();
+
+ /*TODO : change this function to real only as thats what is needed*/
+ ComputePostPredCov_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, hMd->pred_mat_re_fx, exp_pred_re, hMd->pred_mat_im_fx, exp_pred_im, postpred_cov_re_fx, &exp_postpred_cov_re, BINAURAL_CHANNELS );
+
+ /* normalize everything to +-1 range */
+ Word16 gd_16_fx = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, PCM16_TO_FLT_FAC_FX_Q15, &exp_gd );
+ gd_fx = L_deposit_h( gd_16_fx );
+ exp_gd = add( exp_gd, sub( 1, 16 ) );
+
+ Word16 tmp_buff_2[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmp_buff_3[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ Word64 tmp_2 = W_mult_32_32( cov_ii_norm_re_fx[i][j], gd_fx );
+ Word64 tmp_3 = W_mult_32_32( cov_oo_norm_re_fx[i][j], gd_fx );
+ Word16 shift_2 = W_norm( tmp_2 );
+ Word16 shift_3 = W_norm( tmp_3 );
+
+ postpred_cov_re_fx[i][j] = Mpy_32_32( postpred_cov_re_fx[i][j], gd_fx );
+ move32();
+ cov_ii_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_2, shift_2 ) );
+ move32();
+ cov_oo_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_3, shift_3 ) );
+ move32();
+
+ tmp_buff_2[i][j] = exp_cov_ii_norm_re + exp_gd - shift_2;
+ move16();
+ tmp_buff_3[i][j] = exp_cov_oo_norm_re + exp_gd - shift_3;
+ move16();
+ }
+ }
+ Word16 max_2 = MIN16B, max_3 = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ max_2 = s_max( max_2, tmp_buff_2[i][j] );
+ max_3 = s_max( max_3, tmp_buff_3[i][j] );
+ }
+ }
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ cov_ii_norm_re_fx[i][j] = L_shr( cov_ii_norm_re_fx[i][j], max_2 - tmp_buff_2[i][j] );
+ move32();
+ cov_oo_norm_re_fx[i][j] = L_shr( cov_oo_norm_re_fx[i][j], max_3 - tmp_buff_3[i][j] );
+ move32();
+ }
+ }
+
+ exp_postpred_cov_re = add( exp_postpred_cov_re, exp_gd );
+ exp_cov_ii_norm_re = max_2;
+ move16();
+ exp_cov_oo_norm_re = max_3;
+ move16();
+
+ hMd->gd_fx = 0;
+ move16();
+ Word16 exp_gl2 = 0;
+ move16();
+ Word16 check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[0][0], exp_postpred_cov_re, EPSILON_FX, 0 );
+ IF( EQ_16( check_postPred, 1 ) )
+ {
+ Word16 exp_div_res = 0;
+ Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[0][0], postpred_cov_re_fx[0][0], &exp_div_res );
+ exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re );
+ gl2_fx = L_deposit_h( div_res );
+ exp_gl2 = exp_div_res;
+ move16();
+
+ Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gl2_fx, exp_gl2, ONE_IN_Q30, 1 );
+ IF( EQ_16( Cmp1, negate( 1 ) ) )
+ {
+ gl2_fx = ONE_IN_Q30;
+ exp_gl2 = 1;
+ move16();
+ move16();
+ }
+
+ gl2_fx = Sqrt32( gl2_fx, &exp_gl2 );
+ }
+ ELSE
+ {
+ gl2_fx = ONE_IN_Q30;
+ exp_gl2 = 1;
+ move16();
+ move16();
+ }
+
+ Word16 exp_gr2 = 0;
+ check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[1][1], exp_postpred_cov_re, EPSILON_FX, 0 );
+ IF( EQ_16( check_postPred, 1 ) )
+ {
+ Word16 exp_div_res = 0;
+ Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[1][1], postpred_cov_re_fx[1][1], &exp_div_res );
+ exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re );
+ gr2_fx = L_deposit_h( div_res );
+ exp_gr2 = exp_div_res;
+
+ Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gr2_fx, exp_gr2, ONE_IN_Q30, 1 );
+ IF( EQ_16( Cmp1, negate( 1 ) ) )
+ {
+ gr2_fx = ONE_IN_Q30;
+ move16();
+ exp_gr2 = 1;
+ move16();
+ }
+
+ gr2_fx = Sqrt32( gr2_fx, &exp_gr2 );
+ }
+ ELSE
+ {
+ gr2_fx = ONE_IN_Q30;
+ move16();
+ exp_gr2 = 1;
+ move16();
+ }
+
+ Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ pred_mat_buf_re[i][j] = exp_pred_re;
+ move16();
+ pred_mat_buf_im[i][j] = exp_pred_im;
+ move16();
+ }
+ }
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ hMd->pred_mat_re_fx[i][0] = Mpy_32_32( hMd->pred_mat_re_fx[i][0], gl2_fx );
+ move32();
+ hMd->pred_mat_re_fx[i][1] = Mpy_32_32( hMd->pred_mat_re_fx[i][1], gr2_fx );
+ move32();
+ pred_mat_buf_re[i][0] = add( exp_pred_re, exp_gl2 );
+ move16();
+ pred_mat_buf_re[i][1] = add( exp_pred_re, exp_gr2 );
+ move16();
+ }
+
+ IF( EQ_16( real_only, 0 ) )
+ {
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ hMd->pred_mat_im_fx[i][0] = Mpy_32_32( hMd->pred_mat_im_fx[i][0], gl2_fx );
+ move32();
+ hMd->pred_mat_im_fx[i][1] = Mpy_32_32( hMd->pred_mat_im_fx[i][1], gr2_fx );
+ move32();
+
+ pred_mat_buf_im[i][0] = add( exp_pred_im, exp_gl2 );
+ move16();
+ pred_mat_buf_im[i][1] = add( exp_pred_im, exp_gr2 );
+ move16();
+ }
+ }
+
+ Word16 max_exp_pred_re = MIN16B, max_exp_pred_im = MIN16B;
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ max_exp_pred_re = s_max( max_exp_pred_re, pred_mat_buf_re[i][j] );
+ max_exp_pred_im = s_max( max_exp_pred_im, pred_mat_buf_im[i][j] );
+ }
+ }
+
+ FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ hMd->pred_mat_re_fx[i][j] = L_shr( hMd->pred_mat_re_fx[i][j], max_exp_pred_re - pred_mat_buf_re[i][j] );
+ move32();
+ hMd->pred_mat_im_fx[i][j] = L_shr( hMd->pred_mat_im_fx[i][j], max_exp_pred_im - pred_mat_buf_im[i][j] );
+ move32();
+ }
+ }
+
+ hMd->exp_pred_mat_re = max_exp_pred_re;
+ move16();
+ hMd->exp_pred_mat_im = max_exp_pred_im;
+ move16();
+ }
+ }
+
+ return;
+}
+
+static void get_base2_bits(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word16 num_subframes,
+ const Word16 num_quant_strats,
+ const Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ const Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ const Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ const Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ const Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ const Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] )
+{
+ Word16 pred_roll_bits;
+ Word16 d_gain_bits, pitch_gain_bits, pose_idx, q;
+ Word16 pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 bin_ch_2, bin_ch_2_num_sf, bin_ch_num_sf;
+
+ ISAR_SPLIT_REND_POSE_TYPE pose_type;
+
+ FOR( q = 0; q < num_quant_strats; q++ )
+ {
+ pred_yaw_bits[q] = ceil_log_2( pred_quant_pnts_yaw[q] );
+ move16();
+ }
+ pred_roll_bits = ceil_log_2( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS );
+
+ d_gain_bits = ceil_log_2( ISAR_SPLIT_REND_D_QUANT_PNTS );
+ pitch_gain_bits = d_gain_bits;
+ move16();
+
+ FOR( q = 0; q < num_quant_strats; q++ )
+ {
+ base2bits[q] = 0;
+ move32();
+ }
+
+ bin_ch_2 = DEPR_i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
+ bin_ch_2_num_sf = DEPR_i_mult( bin_ch_2, num_subframes );
+ bin_ch_num_sf = DEPR_i_mult( BINAURAL_CHANNELS, num_subframes );
+
+ FOR( q = 0; q < num_quant_strats; q++ )
+ {
+ FOR( pose_idx = 0; pose_idx < sub( pMultiBinPoseData->num_poses, 1 ); pose_idx++ )
+ {
+ pose_type = hBinHrSplitPreRend->pose_type[pose_idx];
+ IF( EQ_32( pose_type, ANY_YAW ) )
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_2_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) );
+ move32();
+#else
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) );
+ move32();
+#endif
+
+
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( d_gain_bits, d_bands_yaw[q] ), num_subframes ) );
+ move32();
+ }
+ ELSE IF( EQ_32( pose_type, PITCH_ONLY ) )
+ {
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) );
+ move32();
+ }
+ ELSE
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_2_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) );
+ move32();
+#else
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_num_sf ) );
+ move32();
+ base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) );
+ move32();
+#endif
+ }
+ }
+ }
+
+ return;
+}
+
+
+static void isar_SplitRenderer_code_md_base2(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word16 num_subframes,
+ const Word16 pred_real_bands_yaw,
+ const Word16 pred_imag_bands_yaw,
+ const Word16 pred_quant_pnts_yaw,
+ const Word16 d_bands_yaw,
+ const Word16 bands_pitch,
+ const Word16 pred_real_bands_roll,
+ const Word16 pred_imag_bands_roll,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word16 pos_idx, b, ch1, ch2, sf_idx;
+ Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses;
+ Word16 min_pred_roll_idx, pred_roll_code_len;
+ Word16 pred_cb_idx;
+ Word32 code;
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
+
+ pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
+ IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
+ {
+ pred_cb_idx = 1;
+ move16();
+ }
+ ELSE
+ {
+ pred_cb_idx = 0;
+ move16();
+ }
+ min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
+ min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
+ min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] );
+ min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] );
+
+ pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx];
+ move16();
+ pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len;
+ move16();
+ gd_code_len = pHuff_cfg->gd_base2_code_len;
+ move16();
+ p_gd_code_len = pHuff_cfg->p_gd_base2_code_len;
+ move16();
+
+ num_poses = pMultiBinPoseData->num_poses;
+ move16();
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ )
+ {
+ IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) )
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
+ }
+ }
+ }
+
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
+ }
+ }
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
+ }
+ }
+#endif
+ FOR( b = 0; b < d_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ code = L_sub( hMd->gd_idx, min_gd_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len );
+ }
+ }
+ ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) )
+ {
+ FOR( b = 0; b < bands_pitch; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ code = L_sub( hMd->gd_idx, min_p_gd_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
+
+ code = L_sub( hMd->gd2_idx, min_p_gd_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
+ }
+ }
+ ELSE
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
+ }
+ }
+ }
+
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
+ }
+ }
+
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_roll_idx );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
+ }
+ }
+#endif
+ }
+ }
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ {
+ static int16_t num_bits = 0;
+ static int16_t cntr = 0;
+ float fnum_bits;
+
+ cntr++;
+
+ num_bits += pBits->bits_written;
+ /* collect bits for every second */
+ if ( cntr == 50 )
+ {
+ cntr = 0;
+ fnum_bits = (float) num_bits / 1000.0f;
+ dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
+ num_bits = 0;
+ }
+ }
+#endif
+ return;
+}
+
+
+static void isar_SplitRenderer_code_md_huff(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const Word16 num_subframes,
+ const Word16 pred_real_bands_yaw,
+ const Word16 pred_imag_bands_yaw,
+ const Word16 pred_quant_pnts_yaw,
+ const Word16 d_bands_yaw,
+ const Word16 bands_pitch,
+ const Word16 pred_real_bands_roll,
+ const Word16 pred_imag_bands_roll,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits )
+{
+ Word16 pos_idx, b, ch1, ch2, sf_idx, num_poses;
+ Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word16 min_pred_idx, max_pred_idx;
+ Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
+ Word32 code, len;
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
+
+ pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
+
+ IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) )
+ {
+ pred_cb_idx = 1;
+ move16();
+ }
+ ELSE
+ {
+ pred_cb_idx = 0;
+ move16();
+ }
+
+ min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] );
+ max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[DEPR_i_mult( sub( pred_quant_pnts_yaw, 1 ), 3 )] );
+ min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] );
+ max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[DEPR_i_mult( sub( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS, 1 ), 3 )] );
+
+ num_poses = pMultiBinPoseData->num_poses;
+ move16();
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ )
+ {
+ IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) )
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+#endif
+ FOR( b = 0; b < d_bands_yaw; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) )
+ {
+ FOR( b = 0; b < bands_pitch; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+
+ isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ ELSE
+ {
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ FOR( b = 0; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+#else
+ FOR( b = 0; b < pred_imag_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+ }
+ FOR( ; b < pred_real_bands_roll; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
+ FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
+ }
+ }
+#endif
+ }
+ }
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ {
+ static int16_t num_bits = 0;
+ static int16_t cntr = 0;
+ float fnum_bits;
+
+ cntr++;
+ num_bits += pBits->bits_written;
+ /* collect bits for every second */
+ IF( cntr == 50 )
+ {
+ cntr = 0;
+ fnum_bits = (float) num_bits / 1000.0f;
+ dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" );
+ num_bits = 0;
+ }
+ }
+#endif
+ return;
+}
+
+static void isar_SplitRenderer_quant_code(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ const IVAS_QUATERNION headPosition,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word16 low_res_pre_rend_rot,
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ const int16_t ro_md_flag,
+#endif
+ const Word32 target_md_bits,
+ Word16 Q_frame )
+{
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word16 q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
+#else
+ Word16 num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
+#endif
+ Word32 overhead_bits, quant_strat_bits, huff_bits, start_bit;
+ Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+#ifdef DEBUG_QUANT_MD_FX
+ float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+ float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
+#endif
+ ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word16 rot_axis_code, num_bits;
+#endif
+
+ IF( low_res_pre_rend_rot )
+ {
+ num_subframes = 1;
+ }
+ ELSE
+ {
+ num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+ }
+
+ overhead_bits = pBits->bits_written;
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS );
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits );
+ if ( num_bits > 0 )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits );
+ }
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS );
+#else
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, ISAR_SPLIT_REND_ROT_AXIS_BITS );
+#endif
+
+ /* code ref pose*/
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ Word16 angle;
+ IVAS_QUATERNION head_pos_euler;
+
+ Quat2EulerDegree_fx( headPosition, &head_pos_euler.z_fx, &head_pos_euler.y_fx, &head_pos_euler.x_fx );
+ angle = (Word16) L_shr_r( head_pos_euler.x_fx, Q22 );
+ angle = add( angle, 180 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
+
+ angle = (Word16) L_shr_r( head_pos_euler.y_fx, Q22 );
+ angle = add( angle, 180 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
+
+ angle = (Word16) L_shr_r( head_pos_euler.z_fx, Q22 );
+ angle = add( angle, 180 );
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
+ }
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
+ pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx,
+ d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats );
+#else
+ isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
+ pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx,
+ d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands );
+#endif
+#ifdef DEBUG_QUANT_MD_FX
+ fixedToFloat_arrL( pred_quantstep_yaw_fx, pred_quantstep_yaw, Q31, ISAR_SPLIT_REND_NUM_QUANT_STRATS );
+ fixedToFloat_arrL( pred_1byquantstep_yaw_fx, pred_1byquantstep_yaw, Q26, ISAR_SPLIT_REND_NUM_QUANT_STRATS );
+#endif
+
+ quant_strat_bits = ceil_log_2( num_quant_strats );
+
+ overhead_bits = L_add( L_add( L_sub( pBits->bits_written, overhead_bits ), quant_strat_bits ), 1 ); /* 1 for base2 vs huff */
+
+ get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw,
+ pred_quant_pnts_yaw,
+ d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits );
+
+ FOR( q = 0; q < num_quant_strats; q++ )
+ {
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
+ {
+ FOR( b = 0; b < pred_imag_bands_yaw[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q]
+#endif
+ );
+ }
+ FOR( ; b < pred_real_bands_yaw[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q]
+#endif
+ );
+ }
+
+ FOR( b = 0; b < d_bands_yaw[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f
+#endif
+ );
+ }
+ }
+ ELSE IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ FOR( b = 0; b < bands_pitch[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f
+#endif
+ );
+ }
+ }
+ ELSE
+ {
+ FOR( b = 0; b < pred_imag_bands_roll[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP
+#endif
+ );
+ }
+ FOR( ; b < pred_real_bands_roll[q]; b++ )
+ {
+ hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame
+#ifdef DEBUG_QUANT_MD_FX
+ ,
+ hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP
+#endif
+ );
+ }
+ }
+ }
+ }
+
+ /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/
+ start_bit = pBits->bits_written;
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
+
+ huff_bits = pBits->bits_written;
+ isar_SplitRenderer_code_md_huff(
+ hBinHrSplitPreRend,
+ pMultiBinPoseData,
+ num_subframes,
+ pred_real_bands_yaw[q],
+ pred_imag_bands_yaw[q],
+ pred_quant_pnts_yaw[q],
+ d_bands_yaw[q],
+ bands_pitch[q],
+ pred_real_bands_roll[q],
+ pred_imag_bands_roll[q],
+ pBits );
+
+ huff_bits = L_sub( pBits->bits_written, huff_bits );
+ test();
+ test();
+ test();
+ IF( GE_32( target_md_bits, ( base2bits[q] + overhead_bits ) ) || GE_32( target_md_bits, ( huff_bits + overhead_bits ) ) || EQ_16( q, sub( num_quant_strats, 1 ) ) )
+ {
+ IF( GT_32( huff_bits, base2bits[q] ) )
+ {
+ pBits->bits_written = start_bit;
+
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
+
+ isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
+ pred_quant_pnts_yaw[q],
+ d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits );
+ }
+ BREAK;
+ }
+
+ pBits->bits_written = start_bit;
+ }
+
+#ifdef SPLIT_MD_CODING_DEBUG
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ int16_t val, quant_strat, ch1, ch2;
+ char filename[200] = "split_md_debug_indices.bin";
+ quant_strat = q;
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
+ {
+ for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ }
+ for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ for ( b = 0; b < bands_pitch[quant_strat]; b++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx;
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx;
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ else
+ {
+ for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2];
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ }
+ for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
+ {
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2];
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, filename );
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return;
+}
+/*-------------------------------------------------------------------------
+ * Function isar_SplitRenderer_GetRotMd()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static Word16 imult1616( Word16 x, Word16 y )
+{
+ assert( (int) x * (int) y < 32768 && (int) x * (int) y >= -32768 );
+ return extract_l( L_mult0( x, y ) );
+}
+
+static void isar_SplitRenderer_GetRotMd_fx(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
+ Word16 exp_cldfb_re,
+ Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
+ Word16 exp_cldfb_im,
+ const Word16 low_res,
+ const Word16 ro_md_flag )
+{
+ Word32 cov_ii_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word32 cov_oo_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word32 cov_io_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word32 cov_ii_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word32 cov_oo_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word32 cov_io_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 };
+ Word16 exp_cov_io_re = 0, exp_cov_io_im = 0;
+ Word16 exp_cov_ii_re = 0, exp_cov_ii_im = 0;
+ Word16 exp_cov_oo_re = 0, exp_cov_oo_im = 0;
+
+ Word16 real_only = 0;
+ Word16 pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2;
+ Word16 num_md_bands, num_poses;
+ const Word16 *pBand_grouping = isar_split_rend_band_grouping;
+
+ push_wmops( "isar_SplitRenderer_GetRotMd_fx" );
+
+ num_md_bands = MAX_SPLIT_REND_MD_BANDS;
+ move16();
+ num_poses = pMultiBinPoseData->num_poses;
+ move16();
+
+ IF( low_res )
+ {
+ num_slots = CLDFB_NO_COL_MAX;
+ move16();
+ num_subframes = 1;
+ move16();
+ }
+ ELSE
+ {
+ num_slots = MAX_PARAM_SPATIAL_SUBFRAMES;
+ move16();
+ num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+ move16();
+ }
+
+ /* compute reference signal covariance */
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ start_slot_idx = imult1616( sf_idx, num_slots );
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ test();
+ IF( LT_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) )
+ {
+ real_only = 0;
+ move16();
+ }
+ ELSE
+ {
+ real_only = 1;
+ move16();
+ }
+
+ ch_s_idx1 = 0;
+
+ ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, cov_ii_re_fx, &exp_cov_ii_re, cov_ii_im_fx, &exp_cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
+
+ /* compute rotated signal covariance */
+ FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
+ {
+ IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL )
+ {
+ IF( GE_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) )
+ {
+ real_only = 1;
+ }
+ }
+ ch_s_idx2 = imult1616( add( pos_idx, 1 ), BINAURAL_CHANNELS );
+
+ ComputeBandedCrossCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_io_re_fx, &exp_cov_io_re, cov_io_im_fx, &exp_cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
+
+ ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_oo_re_fx, &exp_cov_oo_re, cov_oo_im_fx, &exp_cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
+
+ ComputeCoeffs_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only );
+ }
+ }
+ }
+
+ pop_wmops();
+ return;
+}
+/*-------------------------------------------------------------------------
+ * Function isar_rend_CldfbSplitPreRendProcess()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void isar_rend_CldfbSplitPreRendProcess(
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
+ const IVAS_QUATERNION headPosition,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_re,
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 exp_cldfb_im,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 target_md_bits,
+ const Word16 low_res_pre_rend_rot,
+ const Word16 ro_md_flag )
+{
+ push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
+
+ isar_SplitRenderer_GetRotMd_fx( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, low_res_pre_rend_rot, ro_md_flag );
+
+ Word16 num_md_bands, num_poses;
+ Word16 pos_idx, b, sf_idx, num_subframes;
+
+ num_md_bands = MAX_SPLIT_REND_MD_BANDS;
+ num_poses = pMultiBinPoseData->num_poses;
+
+ IF( low_res_pre_rend_rot )
+ {
+ num_subframes = 1;
+ }
+ ELSE
+ {
+ num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+ }
+
+ /*FILE *filePointer_gd, *filePointer_gd2;
+ FILE *filePointer_re, *filePointer_im;
+ filePointer_gd = fopen("Fixed_code_cov_gd_complete.txt", "a");
+ filePointer_gd2 = fopen("Fixed_code_cov_gd2_complete.txt", "a");
+ filePointer_re = fopen("Fixed_code_re_complete.txt", "a");
+ filePointer_im = fopen("Fixed_code_im_complete.txt", "a");*/
+
+#ifdef DUMP_GETROTMD_OUTPUT
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ for ( b = 0; b < num_md_bands; b++ )
+ {
+ for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
+ {
+ if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd );
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 );
+ /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
+ fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
+ }
+ else
+ {
+ for ( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ for ( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ {
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re );
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im );
+ /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]);
+ fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ /*fclose(filePointer_gd);
+ fclose(filePointer_gd2);
+ fclose(filePointer_re);
+ fclose(filePointer_im);*/
+
+ /* Check if rescaling can be simplified/avoid */
+
+ Word16 exp_frame = 0;
+ // Word32 L_temp_max = 0;
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
+ {
+ IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd );
+ exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 );
+ }
+ ELSE
+ {
+ exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re );
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2 );
+#endif
+ exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im );
+ }
+ }
+ }
+ }
+ // exp_frame = s_min( exp_frame, sub( 31, norm_l( L_temp_max ) ) );
+ exp_frame = s_min( exp_frame, 15 ); // Considering the max value as of prediction matrices as 300
+
+ Word16 Q_frame = sub( Q31, exp_frame );
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( b = 0; b < num_md_bands; b++ )
+ {
+ FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
+ {
+ IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ) );
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ) );
+ /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
+ fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
+ }
+ ELSE
+ {
+ FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re, exp_frame ) );
+ Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im, exp_frame ) );
+ }
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re2, BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2, exp_frame ) );
+#endif
+ }
+ }
+ }
+ }
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits, Q_frame );
+#else
+ isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits, Q_frame );
+#endif
+#ifdef DEBUG_QUANT_CODE_OUT
+ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ for ( b = 0; b < num_md_bands; b++ )
+ {
+ for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
+ {
+ if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
+ {
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, Q_frame );
+ hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, Q_frame );
+ /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd);
+ fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/
+ }
+ else
+ {
+ for ( int i = 0; i < BINAURAL_CHANNELS; i++ )
+ {
+ fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i], Q_frame, BINAURAL_CHANNELS );
+ fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i], Q_frame, BINAURAL_CHANNELS );
+ // for ( int j = 0; j < BINAURAL_CHANNELS; j++ )
+ //{
+ // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], Q6 );
+ // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], Q6 );
+ // /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]);
+ // fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/
+ // }
+ }
+ }
+ }
+ }
+ }
+#endif
+#ifdef SPLIT_POSE_CORRECTION_DEBUG
+ float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv;
+ IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler;
+ float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ int16_t sf_idx, pos_idx, b, ch1, ch2;
+ int32_t read_off, write_off;
+ for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
+ {
+ QuaternionsPost[sf_idx].w = -3.0f;
+ QuaternionsPost[sf_idx].x = 0.0f;
+ QuaternionsPost[sf_idx].y = 0.0f;
+ QuaternionsPost[sf_idx].z = 0.0f;
+ }
+
+ hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1;
+ set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData );
+ set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData );
+ for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
+ {
+ Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
+ hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f;
+ hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x );
+ hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y );
+ hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z );
+ }
+ for ( sf_idx = 0; sf_idx < 1; sf_idx++ )
+ {
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ )
+ {
+ hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
+ BIN_HR_SPLIT_REND_MD_HANDLE hMd;
+ hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
+ minv = -1.4f;
+ maxv = 1.4f;
+ step = ( maxv - minv ) / 62.0f;
+ if ( b >= 20 )
+ {
+ float sign;
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f;
+ IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] );
+ hMd->pred_mat_re[ch1][ch2] *= sign;
+ hMd->pred_mat_im[ch1][ch2] = 0.0f;
+ }
+ }
+ }
+
+ for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
+ {
+ for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
+ {
+ quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
+ quant_val = min( maxv, max( quant_val, minv ) );
+ quant_val = (int16_t) roundf( quant_val / step );
+ hMd->pred_mat_re[ch1][ch2] = quant_val * step;
+ hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2];
+
+ quant_val = hMd->pred_mat_im[ch1][ch2];
+ quant_val = min( maxv, max( quant_val, minv ) );
+ quant_val = (int16_t) roundf( quant_val / step );
+ hMd->pred_mat_im[ch1][ch2] = quant_val * step;
+ }
+ }
+ }
+ }
+ }
+
+ for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
+ {
+ mvr2r( (float *) Cldfb_In_BinReal[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
+ mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
+ mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
+ mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
+ isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 );
+
+ {
+ float *pOut[2];
+ char fname[200] = "ref_act_pos.wav";
+ pOut[0] = tmpCrendBuffer[0];
+ pOut[1] = tmpCrendBuffer[1];
+ dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 );
+ }
+ }
+#endif
+
+ pop_wmops();
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinPreRendOpen()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error isar_splitBinPreRendOpen(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ,
+ const int32_t output_Fs
+#endif
+)
+{
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ivas_error error;
+ int16_t ch;
+#endif
+ Word16 pos_idx, sf_idx, bandIdx;
+
+ IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) );
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
+ {
+ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ hBinRend->cldfbSynRotBinDec[i][ch] = NULL;
+ }
+ }
+
+ for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
+ {
+ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+#endif
+
+ FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ FOR( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ )
+ {
+ FOR( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ )
+ {
+ hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd_fx = 0;
+ }
+ }
+ }
+ set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData );
+ set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData );
+
+ isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
+
+#ifdef SPLIT_POSE_CORRECTION_DEBUG
+ ivas_error error;
+ if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#endif
+
+ *hBinHrSplitPreRend = hBinRend;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_splitBinPreRendClose()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_splitBinPreRendClose(
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend )
+{
+ IF( ( *hBinHrSplitPreRend ) != NULL )
+ {
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ {
+ Word16 i, n;
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ )
+ {
+ FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
+ {
+ IF( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL )
+ {
+ deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) );
+ ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL;
+ }
+ }
+ }
+ }
+#endif
+#ifdef SPLIT_POSE_CORRECTION_DEBUG
+ isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend );
+#endif
+
+ free( ( *hBinHrSplitPreRend ) );
+ ( *hBinHrSplitPreRend ) = NULL;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------*
+ * isar_set_split_rend_ht_setup()
+ *
+ *
+ *-------------------------------------------------------------------------*/
+void isar_set_split_rend_ht_setup_fx(
+ SPLIT_REND_WRAPPER *hSplitrend,
+ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
+ Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] )
+{
+ Word16 sf, i, j;
+ IF( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
+ {
+ Quaternions[sf] = Quaternions[0];
+
+ FOR( i = 0; i < 3; i++ )
+ {
+ FOR( j = 0; j < 3; j++ )
+ {
+ Rmat_fx[sf][i][j] = Rmat_fx[0][i][j];
+ move32();
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_init_split_rend_handles()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_init_split_rend_handles(
+ SPLIT_REND_WRAPPER *hSplitRendWrapper )
+{
+ Word16 i;
+
+ hSplitRendWrapper->hBinHrSplitPreRend = NULL;
+ hSplitRendWrapper->hCldfbHandles = NULL;
+ hSplitRendWrapper->hSplitBinLCLDEnc = NULL;
+ hSplitRendWrapper->hLc3plusEnc = NULL;
+
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
+ {
+ hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL;
+ hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = NULL;
+ }
+ hSplitRendWrapper->lc3plusDelaySamples = 0;
+ move32();
+
+ isar_init_multi_bin_pose_data_fx_enc( &hSplitRendWrapper->multiBinPoseData );
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function split_renderer_open_lc3plus()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error split_renderer_open_lc3plus(
+ SPLIT_REND_WRAPPER *hSplitRendWrapper,
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
+ const Word32 OutSampleRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const IVAS_RENDER_FRAMESIZE isar_frame_size
+#else
+ const int16_t num_subframes
+#endif
+)
+{
+ ivas_error error;
+ Word16 i, delayBufferLength;
+ LC3PLUS_CONFIG config;
+#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t isar_frame_size_ms;
+
+ if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#endif
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /* Check configuration validity */
+ if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" );
+ }
+#endif
+
+ config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000;
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000;
+#endif
+ config.samplerate = OutSampleRate;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config.isar_frame_duration_us = isar_frame_size_ms * 1000;
+#endif
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 );
+#endif
+ config.channels = BINAURAL_CHANNELS;
+
+ if ( ( error = ISAR_LC3PLUS_ENC_Open( config,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ),
+#else
+ isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.isar_frame_duration_us / 1000 ) ),
+#endif
+ &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* This returns delay of entire LC3plus chain (enc + dec) */
+ IF( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Alocate buffers for delay compensation */
+ IF( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
+ {
+ delayBufferLength = (Word16) ( OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples );
+ FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
+ {
+ IF( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
+ }
+
+ set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength );
+ IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
+ }
+
+ set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength );
+ }
+ hSplitRendWrapper->lc3plusDelayBuffers_q = 31;
+ }
+ ELSE
+ {
+ /* Delay is always expected to be exactly 2 CLDFB columns */
+ assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 );
+ assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 );
+
+ delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX;
+ FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
+ {
+ IF( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
+ }
+
+ set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength );
+ IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) );
+ }
+
+ set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength );
+ }
+ hSplitRendWrapper->lc3plusDelayBuffers_q = 31;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function splitRendLc3plusEncodeAndWrite()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error splitRendLc3plusEncodeAndWrite(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const int32_t available_bits,
+#endif
+#else
+ const int32_t SplitRendBitRate,
+#endif
+ Word32 *in[],
+ Word16 Q_sig )
+{
+ ivas_error error;
+ int16_t i;
+ int32_t lc3plusBitstreamSize;
+ Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
+ Word16 Q_in[16];
+ assert( hSplitBin->hLc3plusEnc != NULL );
+
+ /* Find next byte boundary and zero-pad to it */
+ while ( pBits->bits_written % 8 != 0 )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
+ }
+
+ for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
+ {
+ channel_ptrs[i] = in[i];
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#endif
+
+ if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 );
+#endif
+ /* Write bitstream */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ set16_fx( Q_in, Q_sig, 16 );
+ move16();
+ if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize, Q_in ) ) != IVAS_ERR_OK )
+#else
+ if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK )
+#endif
+ {
+ return error;
+ }
+
+ pBits->bits_written += 8 * lc3plusBitstreamSize;
+ pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
+ pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
+ pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 );
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 );
+#endif
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_renderMultiTDBinToSplitBinaural()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error isar_renderMultiTDBinToSplitBinaural(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ const IVAS_QUATERNION headPosition,
+ const Word32 SplitRendBitRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const int16_t isar_frame_size_ms,
+#endif
+ const Word16 codec_frame_size_ms,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word16 max_bands,
+ // float *in[],
+ Word32 *in_fx[], // Q11
+ Word16 Q_sig,
+ const Word16 low_res_pre_rend_rot,
+ const Word16 pcm_out_flag,
+ const Word16 ro_md_flag )
+{
+ ivas_error error;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t bit_len, available_bits, target_md_bits, tmp_32;
+#else
+ Word32 bit_len, available_bits, target_md_bits, actual_md_bits, tmp_32;
+#endif
+ Word16 num_cldfb_bands, ch, slot_idx, pos_idx, num_poses;
+ Word16 tmp, tmp_e;
+ Word32 Cldfb_In_BinReal_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 };
+ Word32 Cldfb_In_BinImag_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 };
+ Word16 Q_in = Q_sig, q_final = 0;
+ move16();
+ move16();
+ // float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ // float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ UWord8 useLc3plus;
+ Word32 *in_delayed_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
+ Word16 i;
+ Word32 num_slots;
+
+ push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
+
+ error = IVAS_ERR_OK;
+ num_poses = hSplitBin->multiBinPoseData.num_poses;
+
+ useLc3plus = hSplitBin->hLc3plusEnc != NULL;
+
+ IF( useLc3plus )
+ {
+ /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/
+ // Word16 frame_size = (Word16) ( hSplitBin->hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND );
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.samplerate, FRAMES_PER_SECOND_FX, &tmp_e );
+ Word16 frame_size = shr( tmp, sub( 15, tmp_e ) ); // Q0
+ FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
+ {
+ /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */
+ mvl2l( hSplitBin->lc3plusDelayBuffers_fx[i] + frame_size, hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples );
+ // mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples );
+ in_delayed_fx[i] = hSplitBin->lc3plusDelayBuffers_fx[i];
+ // in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i];
+ mvl2l( in_fx[i], hSplitBin->lc3plusDelayBuffers_fx[i] + hSplitBin->lc3plusDelaySamples, frame_size );
+ // mvr2r(in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, frame_size);
+ }
+ }
+ ELSE
+ {
+ FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
+ {
+ in_delayed_fx[i] = in_fx[i];
+ move32();
+ }
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ actual_md_bits = pBits->bits_written;
+ move32();
+#endif
+
+ test();
+ test();
+ IF( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
+ {
+ Word32 in_delayed_cldfb[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k] = { 0 };
+ FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ )
+ {
+ Copy32( in_delayed_fx[i], in_delayed_cldfb[i], L_FRAME48k );
+ Scale_sig32( in_delayed_cldfb[i], L_FRAME48k, -4 );
+ }
+ Q_sig = sub( Q_sig, 4 );
+ num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
+ move32();
+ num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels;
+ move16();
+ /* CLDFB Analysis*/
+ FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
+ {
+#ifdef SPLIT_POSE_CORRECTION_DEBUG
+ {
+ float *pOut[2];
+ char fname[200] = "ref_out_pos";
+ char tag[2];
+ tag[0] = (char) ( '0' + pos_idx );
+ tag[1] = '\0';
+ strcat( fname, tag );
+ strcat( fname, ".wav" );
+
+ pOut[0] = in_delayed[2 * pos_idx];
+ pOut[1] = in_delayed[2 * pos_idx + 1];
+ dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 );
+ }
+
+#endif
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ HANDLE_CLDFB_FILTER_BANK temp_cldfbAna = hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch];
+ Scale_sig32( temp_cldfbAna->cldfb_state_fx,
+ sub( temp_cldfbAna->p_filter_length, temp_cldfbAna->no_channels ), sub( Q_sig, temp_cldfbAna->Q_cldfb_state ) );
+ temp_cldfbAna->Q_cldfb_state = Q_sig;
+ move16();
+ FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
+ {
+ Word16 Q_cldfb = Q_sig;
+ // floatToFixed_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels);
+ cldfbAnalysis_ts_fx_fixed_q( &( in_delayed_cldfb[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ),
+ Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
+ Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx],
+ max_bands,
+ temp_cldfbAna,
+ &Q_cldfb );
+ /*fixedToFloat_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels);
+ fixedToFloat_arrL(Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);
+ fixedToFloat_arrL(Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);*/
+ /*for (int k = 0; k < max_bands; k++) {
+ printf("\n%f %f ", Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k]);
+ }*/
+ }
+ }
+ }
+ q_final = sub( Q_sig, 5 );
+ }
+
+ IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ // target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
+ target_md_bits = W_extract_l( W_mult0_32_32( isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ), L_FRAME48k ) );
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( target_md_bits, 48000, &tmp_e );
+ target_md_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ actual_md_bits = pBits->bits_written;
+#endif
+ /*scaling to max Q*/
+ Word16 scale_factor = 31;
+ move32();
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ scale_factor = s_min( scale_factor, s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ) );
+ }
+ }
+ scale_factor = sub( scale_factor, 2 );
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ )
+ {
+ FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor );
+ Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor );
+ }
+ }
+ q_final = add( q_final, scale_factor );
+ Word16 exp_cldfb_re = sub( 31, q_final );
+ Word16 exp_cldfb_im = sub( 31, q_final );
+ isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
+ }
+
+ IF( EQ_16( pcm_out_flag, 0 ) )
+ {
+ pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
+ pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD;
+
+ IF( !useLc3plus )
+ {
+ // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
+ available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
+ available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ available_bits = L_sub( available_bits, pBits->bits_written );
+#else
+ actual_md_bits = L_sub( pBits->bits_written, actual_md_bits );
+ available_bits = L_sub( available_bits, actual_md_bits );
+#endif
+ pBits->codec_frame_size_ms = codec_frame_size_ms;
+ move16();
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ pBits->isar_frame_size_ms = isar_frame_size_ms;
+ move16();
+#endif
+ isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final );
+ }
+ ELSE
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
+ IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in_fx, Q_in ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
+ IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in_flt ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#endif
+ }
+ }
+ ELSE
+ {
+ pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
+ pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
+ }
+
+ /*zero pad*/
+ IF( pcm_out_flag )
+ {
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e );
+ bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
+ // bit_len = SplitRendBitRate / FRAMES_PER_SEC;
+ }
+ ELSE
+ {
+ IF( !useLc3plus )
+ {
+ // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
+
+ bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
+ bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+ }
+ ELSE
+ {
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( (Word32) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
+ bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
+ // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
+ // bit_len = SplitRendBitRate * bit_len / 1000;
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e );
+ bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+ }
+ }
+
+
+ WHILE( LT_32( pBits->bits_written, bit_len ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
+ }
+
+ pop_wmops();
+
+ return error;
+}
+
+/*-------------------------------------------------------------------------
+ * Function lc3plusTimeAlignCldfbPoseCorr()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void lc3plusTimeAlignCldfbPoseCorr(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word16 *Q_in )
+{
+ Word32 Cldfb_In_BinReal_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_In_BinImag_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
+ Word16 pose, ch, slot_idx;
+ Word32 *bufRead_fx, *bufWrite_fx;
+
+ IF( GT_16( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) )
+ {
+ // hSplitBin->lc3plusDelayBuffers_q[0] = *Q_in;
+ FOR( Word16 i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ )
+ {
+
+ Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], 4 * CLDFB_NO_CHANNELS_MAX, sub( *Q_in, hSplitBin->lc3plusDelayBuffers_q ) );
+ }
+ hSplitBin->lc3plusDelayBuffers_q = *Q_in;
+ }
+ ELSE
+ {
+ FOR( Word16 i = 0; i < CLDFB_NO_COL_MAX; i++ )
+ {
+ for ( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) );
+ Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) );
+ }
+ }
+ *Q_in = hSplitBin->lc3plusDelayBuffers_q;
+ }
+
+ FOR( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose )
+ {
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ++ch )
+ {
+ bufRead_fx = hSplitBin->lc3plusDelayBuffers_fx[pose * BINAURAL_CHANNELS + ch];
+ bufWrite_fx = bufRead_fx;
+
+ /* Save last 2 columns for next frame */
+ FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
+ {
+ Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
+ Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
+ }
+
+ /* Delay existing columns by 2 slots */
+ /*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */
+ FOR( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx )
+ {
+ Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
+ Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
+ }
+
+ /* Fill 2 first columns from buffer */
+ FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
+ {
+ Copy32( bufRead_fx, Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
+ bufRead_fx += CLDFB_NO_CHANNELS_MAX;
+ Copy32( bufRead_fx, Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX );
+ bufRead_fx += CLDFB_NO_CHANNELS_MAX;
+ }
+
+ /* Copy last 2 columns to buffer */
+ FOR( slot_idx = 0; slot_idx < 2; ++slot_idx )
+ {
+ Copy32( Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX );
+ bufWrite_fx += CLDFB_NO_CHANNELS_MAX;
+ Copy32( Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX );
+ bufWrite_fx += CLDFB_NO_CHANNELS_MAX;
+ }
+ }
+ }
+
+ return;
+}
+
+#endif
diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..b290ca12a7e4bc00a8e43bdef2513535489c0f8b
--- /dev/null
+++ b/lib_isar/isar_splitRenderer_utils.c
@@ -0,0 +1,1741 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include
+#include "ivas_prot.h"
+#include "prot.h"
+#include "cnst.h"
+#include "isar_cnst.h"
+#include "ivas_rom_rend.h"
+#include "ivas_rom_com.h"
+#include "isar_rom_post_rend.h"
+#include "ivas_rom_binauralRenderer.h"
+#include "lib_isar_post_rend.h"
+#include "isar_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+#include "basop_settings.h"
+#include "prot_fx2.h"
+
+#include "basop_util.h"
+
+
+/*-------------------------------------------------------------------------
+ * Function ivas_mat_mult_2by2_complex()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void ivas_cmult_fix( Word32 in1_re_fx, Word16 exp_re1, Word32 in1_im_fx, Word16 exp_im1, Word32 in2_re_fx, Word16 exp_re2, Word32 in2_im_fx, Word16 exp_im2, Word32 *out1_re_fx, Word32 *out1_im_fx, Word16 *exp_out1_re, Word16 *exp_out1_im )
+{
+ Word16 shift_1 = W_norm( W_mult_32_32( in1_re_fx, in2_re_fx ) );
+ Word16 shift_2 = W_norm( W_mult_32_32( in1_im_fx, in2_im_fx ) );
+ Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_re_fx ), shift_1 ) );
+ Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( in1_im_fx, in2_im_fx ), shift_2 ) );
+ Word16 exp_tmp1 = 0;
+ move16();
+ *out1_re_fx = BASOP_Util_Add_Mant32Exp( tmp1, exp_re1 + exp_re2 - shift_1, L_negate( tmp2 ), exp_im1 + exp_im2 - shift_2, &exp_tmp1 );
+ *exp_out1_re = exp_tmp1;
+ Word16 shift_3 = W_norm( W_mult_32_32( in1_re_fx, in2_im_fx ) );
+ Word16 shift_4 = W_norm( W_mult_32_32( in2_re_fx, in1_im_fx ) );
+ Word32 tmp3 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_im_fx ), shift_3 ) );
+ Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( in2_re_fx, in1_im_fx ), shift_4 ) );
+ Word16 exp_tmp2 = 0;
+ move16();
+ *out1_im_fx = BASOP_Util_Add_Mant32Exp( tmp3, exp_re1 + exp_im2 - shift_3, tmp4, exp_re2 + exp_im1 - shift_4, &exp_tmp2 );
+ *exp_out1_im = exp_tmp2;
+ move16();
+}
+
+void ivas_calculate_abs_fx( Word32 re_fx, Word16 exp_re, Word32 im_fx, Word16 exp_im, Word32 *out_fx, Word16 *exp_out )
+{
+ Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) );
+ Word16 shift_2 = W_norm( W_mult_32_32( im_fx, im_fx ) );
+ Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) );
+ Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( im_fx, im_fx ), shift_2 ) );
+ Word16 exp_tmp1 = 0;
+ Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1, exp_re + exp_re - shift_1, tmp2, exp_im + exp_im - shift_2, &exp_tmp1 );
+ *out_fx = Sqrt32( tmp3, &exp_tmp1 );
+ *exp_out = exp_tmp1;
+}
+
+void ivas_calculate_rabs_fx( Word32 re_fx, Word16 exp_re, Word32 *out_fx, Word16 *exp_out )
+{
+ Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) );
+ Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) );
+ Word16 exp_tmp1 = exp_re + exp_re - shift_1;
+ Word32 tmp2 = Sqrt32( tmp1, &exp_tmp1 );
+ *out_fx = tmp2;
+ *exp_out = exp_tmp1;
+}
+
+void isar_mat_mult_2by2_complex_fx(
+ Word32 in_re1_fx[2][2],
+ Word16 exp_re1,
+ Word32 in_im1_fx[2][2],
+ Word16 exp_im1,
+ Word32 in_re2_fx[2][2],
+ Word16 exp_re2,
+ Word32 in_im2_fx[2][2],
+ Word16 exp_im2,
+ Word32 out_re2_fx[2][2],
+ Word16 *final_exp_re_1,
+ Word32 out_im2_fx[2][2],
+ Word16 *final_exp_im_1 )
+{
+ Word16 i, j;
+ Word32 tmp_re_fx, tmp_im_fx;
+
+ Word16 exp_tmp1 = 0, exp_tmp2 = 0, exp_tmp3 = 0, exp_tmp4 = 0;
+ Word16 final_exp_re = 0, final_exp_im = 0;
+ Word16 BuffExp_re[2][2];
+ Word16 BuffExp_im[2][2];
+
+ FOR( i = 0; i < 2; i++ )
+ {
+ FOR( j = 0; j < 2; j++ )
+ {
+ ivas_cmult_fix( in_re1_fx[i][0], exp_re1, in_im1_fx[i][0], exp_im1, in_re2_fx[0][j], exp_re2, in_im2_fx[0][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 );
+
+ out_re2_fx[i][j] = tmp_re_fx;
+ move32();
+ out_im2_fx[i][j] = tmp_im_fx;
+ move32();
+
+ ivas_cmult_fix( in_re1_fx[i][1], exp_re1, in_im1_fx[i][1], exp_im1, in_re2_fx[1][j], exp_re2, in_im2_fx[1][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp3, &exp_tmp4 );
+
+ out_re2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_re2_fx[i][j], exp_tmp1, tmp_re_fx, exp_tmp3, &final_exp_re );
+ move32();
+ out_im2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_im2_fx[i][j], exp_tmp2, tmp_im_fx, exp_tmp4, &final_exp_im );
+ move32();
+
+ BuffExp_re[i][j] = final_exp_re;
+ move16();
+ BuffExp_im[i][j] = final_exp_im;
+ move16();
+ }
+ }
+
+ Word16 max_exp_re = 0;
+ Word16 max_exp_im = 0;
+ move16();
+ move16();
+ FOR( i = 0; i < 2; i++ )
+ {
+ FOR( j = 0; j < 2; j++ )
+ {
+ max_exp_re = s_max( max_exp_re, BuffExp_re[i][j] );
+ max_exp_im = s_max( max_exp_im, BuffExp_im[i][j] );
+ }
+ }
+
+ FOR( i = 0; i < 2; i++ )
+ {
+ FOR( j = 0; j < 2; j++ )
+ {
+ out_re2_fx[i][j] = L_shr( out_re2_fx[i][j], max_exp_re - BuffExp_re[i][j] );
+ move32();
+ out_im2_fx[i][j] = L_shr( out_im2_fx[i][j], max_exp_im - BuffExp_im[i][j] );
+ move32();
+ }
+ }
+ *final_exp_re_1 = max_exp_re;
+ move16();
+ *final_exp_im_1 = max_exp_im;
+ move16();
+
+ return;
+}
+
+void ivas_mat_mult_2by2_complex(
+ float in_re1[2][2],
+ float in_im1[2][2],
+ float in_re2[2][2],
+ float in_im2[2][2],
+ float out_re2[2][2],
+ float out_im2[2][2] )
+{
+ int16_t i, j;
+ float tmp_re, tmp_im;
+
+ for ( i = 0; i < 2; i++ )
+ {
+ for ( j = 0; j < 2; j++ )
+ {
+ IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], in_re2[0][j], in_im2[0][j], tmp_re, tmp_im );
+ out_re2[i][j] = tmp_re;
+ out_im2[i][j] = tmp_im;
+
+ IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], in_re2[1][j], in_im2[1][j], tmp_re, tmp_im );
+ out_re2[i][j] += tmp_re;
+ out_im2[i][j] += tmp_im;
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_SPLIT_REND_BITStream_init()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void ISAR_SPLIT_REND_BITStream_init(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 buf_len_bytes,
+ UWord8 *pbuf )
+{
+ pBits->bits_buf = pbuf;
+ pBits->buf_len = buf_len_bytes;
+ move32();
+ pBits->bits_read = 0;
+ move32();
+ pBits->bits_written = 0;
+ move32();
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_split_rend_huffman_dec_init_min_max_len()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_split_rend_huffman_dec_init_min_max_len(
+ isar_split_rend_huffman_cfg_t *p_huff_cfg )
+{
+ Word16 i, code_len;
+ const Word32 *codebook;
+
+ codebook = p_huff_cfg->codebook;
+
+ p_huff_cfg->min_len = p_huff_cfg->sym_len;
+ move16();
+ p_huff_cfg->max_len = 0;
+ move16();
+
+ FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
+ {
+ code_len = extract_l( codebook[1] );
+ IF( GT_16( p_huff_cfg->min_len, code_len ) )
+ {
+ p_huff_cfg->min_len = code_len;
+ move16();
+ }
+ IF( LT_16( p_huff_cfg->max_len, code_len ) )
+ {
+ p_huff_cfg->max_len = code_len;
+ move16();
+ }
+ codebook = codebook + 3;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function is_idx_present()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static Word16 is_idx_present(
+ Word16 *idx_list,
+ const Word16 idx,
+ const Word16 len )
+{
+ Word16 i;
+
+ FOR( i = 0; i < len; i++ )
+ {
+ IF( EQ_16( idx_list[i], idx ) )
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function ivas_split_huff_get_idx_trav_list()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static void ivas_split_huff_get_idx_trav_list(
+ Word16 *idx_list,
+ isar_split_rend_huffman_cfg_t *p_huff_cfg )
+{
+ Word16 i, j, min_idx;
+ Word32 min_bits;
+ const Word32 *codebook;
+
+ FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
+ {
+ idx_list[i] = -1;
+ move16();
+ }
+
+ FOR( i = 0; i < p_huff_cfg->sym_len; i++ )
+ {
+ codebook = p_huff_cfg->codebook;
+ min_bits = p_huff_cfg->max_len;
+ move16();
+ min_idx = -1;
+ move16();
+ FOR( j = 0; j < p_huff_cfg->sym_len; j++ )
+ {
+ test();
+ IF( GE_32( min_bits, codebook[1] ) && EQ_16( is_idx_present( idx_list, j, i + 1 ), 0 ) )
+ {
+ min_bits = codebook[1];
+ move16();
+ min_idx = j;
+ move16();
+ }
+ codebook += 3;
+ }
+ idx_list[i] = min_idx;
+ move16();
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_split_rend_init_huff_cfg()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_split_rend_init_huff_cfg(
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg )
+{
+ pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0];
+ pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] );
+ pHuff_cfg->pred_base2_code_len[0] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+ pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0];
+ pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] );
+ pHuff_cfg->pred_base2_code_len[1] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+
+ pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0];
+ pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll );
+ pHuff_cfg->pred_roll_base2_code_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+ pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0];
+ pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd );
+ pHuff_cfg->gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+ pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0];
+ pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd );
+ pHuff_cfg->p_gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+ pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0];
+ pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
+ move16();
+ isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff );
+ ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff );
+ pHuff_cfg->p_gd_diff_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL;
+ move16();
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function set_fix_rotation_mat()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void set_fix_rotation_mat_fx(
+ Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ Word32 cos_yaw, sin_yaw;
+ Word16 pos_idx;
+ Word16 ind = 0;
+
+ // pMultiBinPoseData->relative_head_poses can take only take -30, -22.5, -15, 0, 15, 22.5 and 30 degrees.
+ // cos(180 - theta) = cos(theta).
+ // Need only 4 values in LUT
+
+ FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ )
+ {
+ ind = extract_l( L_shr( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), Q22 ) );
+
+ ind = shr( ind, 3 ); /* Values: 0, 1, 2 and 3 */
+ cos_yaw = ivas_split_rend_fix_pos_rot_mat_cos_fx[ind]; /* Q31 */
+ sin_yaw = 0;
+
+ fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; /* Q31 */
+ fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; /* Q31 */
+ fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; /* Q31 */
+ fix_pos_rot_mat[pos_idx][1][0] = L_negate( sin_yaw ); /* Q31 */
+ }
+
+ return;
+}
+void set_fix_rotation_mat(
+ float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ float yaw_a, cos_yaw, sin_yaw;
+ int16_t pos_idx;
+ yaw_a = 0.0f;
+
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ yaw_a = pMultiBinPoseData->relative_head_poses[pos_idx + 1][0];
+ cos_yaw = cosf( EVS_PI * yaw_a / 180.0f );
+ sin_yaw = sinf( EVS_PI * yaw_a / 180.0f );
+ sin_yaw = 0.0f;
+ fix_pos_rot_mat[pos_idx][0][0] = cos_yaw;
+ fix_pos_rot_mat[pos_idx][1][1] = cos_yaw;
+ fix_pos_rot_mat[pos_idx][0][1] = sin_yaw;
+ fix_pos_rot_mat[pos_idx][1][0] = -1.0f * sin_yaw;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function set_pose_types()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void set_pose_types_fx(
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ Word16 pos_idx;
+
+ FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), EPSILON_FX ) )
+ {
+ pose_type[pos_idx] = ANY_YAW;
+ move32();
+ }
+ ELSE IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][2] ), EPSILON_FX ) )
+ {
+ pose_type[pos_idx] = ANY_ROLL;
+ move32();
+ }
+ ELSE
+ {
+ pose_type[pos_idx] = PITCH_ONLY;
+ move32();
+ }
+ }
+
+ return;
+}
+void set_pose_types(
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ int16_t pos_idx;
+
+ for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ )
+ {
+ if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] ) > EPSILON )
+ {
+ pose_type[pos_idx] = ANY_YAW;
+ }
+ else if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][2] ) > EPSILON )
+ {
+ pose_type[pos_idx] = ANY_ROLL;
+ }
+ else
+ {
+ pose_type[pos_idx] = PITCH_ONLY;
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function wrap_a()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word16 wrap_a(
+ Word16 val,
+ const Word16 min_val,
+ const Word16 max_val )
+{
+ IF( LT_16( val, min_val ) )
+ {
+ val = add( add( sub( max_val, min_val ), val ), 1 );
+ }
+
+ IF( GT_16( val, max_val ) )
+ {
+ val = sub( sub( add( min_val, val ), max_val ), 1 );
+ }
+
+ return val;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_SplitRenderer_getdiagdiff()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_SplitRenderer_getdiagdiff(
+ Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
+ const Word16 sign,
+ const Word16 min_val,
+ const Word16 max_val )
+{
+ out_idx[0][0] = in_idx[0][0];
+ move16();
+ out_idx[0][1] = in_idx[0][1];
+ move16();
+ // DEPR_i_mult used instead of i_mult becuase it is not available
+ out_idx[1][1] = add( in_idx[1][1], DEPR_i_mult( sign, out_idx[0][0] ) );
+ move16();
+ out_idx[1][1] = wrap_a( out_idx[1][1], min_val, max_val );
+ move16();
+ out_idx[1][0] = add( in_idx[1][0], DEPR_i_mult( sign, out_idx[0][1] ) );
+ move16();
+ out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val );
+ move16();
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_SPLIT_REND_BITStream_read_int32()
+ *
+ *
+ *------------------------------------------------------------------------*/
+Word32 ISAR_SPLIT_REND_BITStream_read_int32(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 bits )
+{
+ Word32 val, k, bit_val;
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ assert( ( pBits->bits_written - pBits->bits_read ) >= bits );
+ assert( bits <= 32 );
+#endif
+
+ /* write bit by bit */
+ val = 0;
+ move32();
+ FOR( k = L_sub( bits, 1 ); k >= 0; k-- )
+ {
+ bit_val = NE_32( L_and( pBits->bits_buf[L_shr( pBits->bits_read, 3 )], ( L_shl( 1, (Word16) ( L_and( pBits->bits_read, 7 ) ) ) ) ), 0 );
+ val = L_or( val, L_shl( bit_val, (Word16) k ) );
+ pBits->bits_read = L_add( pBits->bits_read, 1 );
+ }
+
+ return val;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_SPLIT_REND_BITStream_write_int32()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void ISAR_SPLIT_REND_BITStream_write_int32(
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ const Word32 val,
+ const Word32 bits )
+{
+ Word32 mask, k;
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ /*protection check*/
+ if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) )
+ {
+ assert( 0 );
+ }
+#endif
+
+ mask = L_shl( 1, extract_l( L_sub( bits, 1 ) ) );
+ /* write bit by bit */
+ FOR( k = 0; k < bits; k++ )
+ {
+ IF( L_and( val, mask ) )
+ {
+ pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_or( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) );
+ }
+ ELSE
+ {
+ pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_and( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], ~L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) );
+ }
+ pBits->bits_written++;
+ mask = L_shr( mask, 1 );
+ }
+
+ return;
+}
+
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+/*-------------------------------------------------------------------------
+ * ivas_mat_mult_2by2_complex()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_log_cldfb2wav_data(
+ float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ HANDLE_CLDFB_FILTER_BANK *cldfbSyn,
+ const int16_t num_chs,
+ const int16_t num_freq_bands,
+ const int32_t output_Fs,
+ const int16_t num_slots,
+ const int16_t start_slot_idx,
+ const char *filename )
+{
+ float *RealBuffer[CLDFB_NO_COL_MAX];
+ float *ImagBuffer[CLDFB_NO_COL_MAX];
+ float pcm_out[BINAURAL_CHANNELS][L_FRAME48k];
+ float *pPcm[BINAURAL_CHANNELS];
+ float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ int16_t sf, ch;
+
+ assert( num_chs <= BINAURAL_CHANNELS );
+ for ( ch = 0; ch < num_chs; ch++ )
+ {
+ for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ )
+ {
+ mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands );
+ mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands );
+ RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf];
+ ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf];
+ }
+ cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] );
+ pPcm[ch] = pcm_out[ch];
+ }
+ dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs );
+
+ return;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_get_split_rend_md_target_brate()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word32 isar_get_split_rend_md_target_brate(
+ const Word32 SplitRendBitRate,
+ const Word16 pcm_out_flag )
+{
+ Word32 md_bitrate;
+
+ IF( EQ_16( pcm_out_flag, 1 ) )
+ {
+ md_bitrate = SplitRendBitRate;
+ move32();
+ }
+ ELSE
+ {
+ SWITCH( SplitRendBitRate )
+ {
+ case SPLIT_REND_768k:
+ {
+ md_bitrate = 256000;
+ move32();
+ BREAK;
+ }
+ case SPLIT_REND_512k:
+ {
+ md_bitrate = 128000;
+ move32();
+ BREAK;
+ }
+ case SPLIT_REND_384k:
+ {
+ md_bitrate = 128000;
+ move32();
+ BREAK;
+ }
+ default:
+ {
+ return -1;
+ }
+ }
+ }
+
+ return md_bitrate;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_get_lcld_bitrate()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word32 isar_get_lcld_bitrate(
+ const Word32 SplitRendBitRate,
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode )
+{
+ IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
+ {
+ SWITCH( SplitRendBitRate )
+ {
+ case SPLIT_REND_768k:
+ {
+ return IVAS_512k;
+ }
+ case SPLIT_REND_512k:
+ {
+ return IVAS_384k;
+ }
+ case SPLIT_REND_384k:
+ {
+ return IVAS_256k;
+ }
+ default:
+ {
+ assert( 0 );
+ }
+ }
+ }
+ ELSE
+ {
+ return SplitRendBitRate;
+ }
+
+ return -1;
+}
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+/*-------------------------------------------------------------------------
+ * Function isar_get_lc3plus_bitrate()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word32 isar_get_lc3plus_bitrate(
+ const Word32 SplitRendBitRate,
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
+ const Word16 split_prerender_frame_size_ms )
+{
+ IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
+ {
+ Word32 inBandMdBps = (Word32) ( 8 * 1000 / split_prerender_frame_size_ms );
+ return L_sub( isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ), inBandMdBps );
+ }
+
+ IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) )
+ {
+ return SplitRendBitRate;
+ }
+
+ /* Should not be reached */
+ assert( 0 );
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_get_lc3plus_bitrate_id()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word8 isar_get_lc3plus_bitrate_id(
+ const Word32 SplitRendBitRate )
+{
+ SWITCH( SplitRendBitRate )
+ {
+ case SPLIT_REND_768k:
+ {
+ return 4;
+ }
+ case SPLIT_REND_512k:
+ {
+ return 3;
+ }
+ case SPLIT_REND_384k:
+ {
+ return 2;
+ }
+ case SPLIT_REND_320k:
+ {
+ return 1;
+ }
+ case SPLIT_REND_256k:
+ {
+ return 0;
+ }
+ default:
+ {
+ BREAK;
+ }
+ }
+
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function ivas_mat_mult_2by2_complex()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word32 isar_get_lc3plus_size_from_id(
+ const Word8 SplitRendBitRateId,
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
+ const Word16 split_prerender_frame_size_ms )
+{
+ Word32 bitrate;
+
+ SWITCH( SplitRendBitRateId )
+ {
+ case 4:
+ {
+ bitrate = SPLIT_REND_768k;
+ move32();
+ BREAK;
+ }
+ case 3:
+ {
+ bitrate = SPLIT_REND_512k;
+ move32();
+ BREAK;
+ }
+ case 2:
+ {
+ bitrate = SPLIT_REND_384k;
+ move32();
+ BREAK;
+ }
+ case 1:
+ {
+ bitrate = SPLIT_REND_320k;
+ move32();
+ BREAK;
+ }
+ case 0:
+ {
+ bitrate = SPLIT_REND_256k;
+ move32();
+ BREAK;
+ }
+ default:
+ {
+ bitrate = -1;
+ move32();
+ BREAK;
+ }
+ }
+
+ bitrate = isar_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms );
+
+ /* Return size in bytes */
+ return (Word32) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 );
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Function isar_split_rend_validate_config()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error isar_split_rend_validate_config(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
+ const Word16 is_pcm_out )
+{
+ /* Valid DOF range is 0-3 */
+ test();
+ IF( LT_16( pSplitRendConfig->dof, 0 ) || GT_16( pSplitRendConfig->dof, 3 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Valid DOF range is 0-3" );
+ }
+
+ /* Only CLDFB pose correction supports HQ mode */
+ test();
+ IF( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) && NE_16( pSplitRendConfig->hq_mode, 0 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" );
+ }
+
+ /* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */
+ test();
+ test();
+ test();
+ IF( ( EQ_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && NE_16( pSplitRendConfig->dof, 0 ) ) ||
+ ( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && EQ_16( pSplitRendConfig->dof, 0 ) ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" );
+ }
+
+ IF( NE_16( pSplitRendConfig->codec_frame_size_ms, 0 ) ) /* 0 means "default for current codec", will be set to actual value at a later stage */
+ {
+ test();
+ test();
+ test();
+ IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LCLD ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 20 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" );
+ }
+
+ test();
+ test();
+ IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" );
+ }
+ }
+
+ /* Validate bitrate */
+ IF( EQ_16( is_pcm_out, 0 ) )
+ {
+ SWITCH( pSplitRendConfig->splitRendBitRate )
+ {
+ case SPLIT_REND_256k:
+ IF( NE_16( pSplitRendConfig->dof, 0 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" );
+ }
+ BREAK;
+ case SPLIT_REND_320k:
+ /* Only valid with 0 DOF */
+ IF( NE_16( pSplitRendConfig->dof, 0 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" );
+ }
+ BREAK;
+ case SPLIT_REND_384k:
+ case SPLIT_REND_512k:
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ case SPLIT_REND_768k:
+#endif
+ /* Always valid */
+ BREAK;
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ case SPLIT_REND_768k:
+ test();
+ IF( EQ_16( pSplitRendConfig->dof, 0 ) && EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" );
+ }
+ BREAK;
+#endif
+ default:
+ return IVAS_ERR_LC3PLUS_INVALID_BITRATE;
+ }
+ }
+ ELSE
+ {
+ IF( EQ_16( pSplitRendConfig->dof, 1 ) ){
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 34000 ) ){
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" );
+ }
+#else
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" );
+ }
+#endif
+}
+ELSE IF( EQ_16( pSplitRendConfig->dof, 2 ) ){
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" );
+}
+#else
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 66000 ) ){
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" );
+}
+#endif
+}
+ELSE IF( EQ_16( pSplitRendConfig->dof, 3 ) )
+{
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 82000 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" );
+ }
+#else
+ IF( LT_32( pSplitRendConfig->splitRendBitRate, 128000 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" );
+ }
+#endif
+}
+}
+
+return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_split_rend_get_quant_params()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_split_rend_get_quant_params_fx(
+ const Word16 num_md_bands,
+ Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+ Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ const Word16 ro_flag,
+#endif
+ Word16 *num_quant_strats
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ ,
+ Word16 *num_complex_bands
+#endif
+)
+{
+ Word16 q;
+
+ *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS;
+ move16();
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW;
+ move16();
+ assert( *num_complex_bands <= num_md_bands );
+#endif
+
+ pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
+ move16();
+ pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31;
+ move32();
+ pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26;
+ move32();
+ FOR( q = 1; q < *num_quant_strats; q++ )
+ {
+ pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
+ move16();
+ pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31;
+ move32();
+ pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26;
+ move32();
+ }
+
+ FOR( q = 0; q < *num_quant_strats; q++ )
+ {
+ pred_real_bands_yaw[q] = num_md_bands;
+ move16();
+ pred_real_bands_roll[q] = num_md_bands;
+ move16();
+ }
+
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ pred_imag_bands_yaw[0] = num_md_bands;
+ move16();
+ pred_imag_bands_roll[0] = num_md_bands;
+ move16();
+ pred_imag_bands_yaw[1] = num_md_bands;
+ move16();
+ pred_imag_bands_roll[1] = num_md_bands;
+ move16();
+
+ FOR( q = 2; q < *num_quant_strats; q++ )
+ {
+ pred_imag_bands_yaw[q] = LT_16( q, sub( *num_quant_strats, 1 ) ) ? num_md_bands : *num_complex_bands;
+ move16();
+ pred_imag_bands_roll[q] = *num_complex_bands;
+ move16();
+ }
+#else
+ IF( ro_flag )
+ {
+ FOR( q = 0; q < *num_quant_strats; q++ )
+ {
+ pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH;
+ move16();
+ }
+ }
+ ELSE
+ {
+ FOR( q = 0; q < *num_quant_strats - 2; q++ )
+ {
+ pred_imag_bands_yaw[q] = num_md_bands;
+ move16();
+ }
+ pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH;
+ move16();
+ pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW;
+ move16();
+ }
+
+ FOR( q = 0; q < *num_quant_strats; q++ )
+ {
+ pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH;
+ move16();
+ }
+#endif
+
+ FOR( q = 0; q < *num_quant_strats; q++ )
+ {
+ d_bands_yaw[q] = 0;
+ move16();
+ bands_pitch[q] = num_md_bands;
+ move16();
+ }
+
+ return;
+}
+
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+/*-------------------------------------------------------------------------
+ * Function isar_renderSplitGetRot_axisNumBits()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word16 isar_renderSplitGetRot_axisNumBits(
+ const Word16 dof )
+{
+ Word16 num_bits;
+ IF( dof < 3 )
+ {
+ num_bits = 2;
+ }
+ ELSE
+ {
+ num_bits = 0;
+ }
+ return num_bits;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_renderSplitGetRot_axisFromCode()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
+ const Word16 dof,
+ const Word16 code )
+{
+ ISAR_SPLIT_REND_ROT_AXIS rot_axis;
+
+ IF( dof == 1 )
+ {
+ rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
+ }
+ else if ( dof == 2 )
+ {
+ IF( code == 0 )
+ {
+ rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
+ }
+ ELSE
+ {
+ rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH;
+ }
+ }
+ ELSE
+ {
+ rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS;
+ }
+
+ return rot_axis;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_renderSplitGetCodeFromRot_axis()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+Word16 isar_renderSplitGetCodeFromRot_axis(
+ const Word16 dof,
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
+ Word16 *num_bits )
+{
+ Word16 code = 0;
+ IF( dof == 1 )
+ {
+ code = (Word16) rot_axis;
+ }
+ else if ( dof == 2 )
+ {
+ IF( rot_axis == DEFAULT_AXIS )
+ {
+ code = (Word16) rot_axis;
+ }
+ ELSE
+ {
+ code = (Word16) ( rot_axis - YAW_PITCH ) + 1;
+ }
+ }
+ ELSE
+ {
+ code = (Word16) DEFAULT_AXIS;
+ }
+ *num_bits = isar_renderSplitGetRot_axisNumBits( dof );
+
+ return code;
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Function isar_renderSplitGetMultiBinPoseData()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_renderSplitGetMultiBinPoseData_fx(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis )
+{
+ Word16 pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses;
+ const Word32 *relative_yaw_angles;
+ const Word32 *relative_pitch_angles;
+ const Word32 *relative_roll_angles;
+
+ FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
+ move32();
+ }
+
+ /* 0 DOF defaults */
+ num_yaw_poses = 0;
+ move16();
+ num_pitch_poses = 0;
+ move16();
+ num_roll_poses = 0;
+ move16();
+
+ /* defaults for all DOF except 3DOF HQ */
+ relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx;
+ relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx;
+ relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx;
+
+ IF( EQ_16( pSplit_rend_config->dof, 1 ) )
+ {
+ SWITCH( rot_axis )
+ {
+ case DEFAULT_AXIS:
+ case YAW:
+ {
+ num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+ case PITCH:
+ {
+ num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+ case ROLL:
+ {
+ num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+ default:
+ {
+ assert( 0 && "unsupported rotation axis value" );
+ }
+ }
+ }
+ ELSE IF( EQ_16( pSplit_rend_config->dof, 2 ) )
+ {
+ SWITCH( rot_axis )
+ {
+ case DEFAULT_AXIS:
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ case YAW:
+ case PITCH:
+#endif
+ case YAW_PITCH:
+ {
+ num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
+ move16();
+ num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ case ROLL:
+#endif
+ case YAW_ROLL:
+ {
+ num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
+ move16();
+ num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+ case PITCH_ROLL:
+ {
+ num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
+ move16();
+ num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
+ move16();
+ BREAK;
+ }
+ default:
+ {
+ assert( 0 && "unsupported rotation axis value" );
+ }
+ }
+ }
+ ELSE IF( EQ_16( pSplit_rend_config->dof, 3 ) )
+ {
+ IF( EQ_16( pSplit_rend_config->hq_mode, 1 ) )
+ {
+ relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx;
+ relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx;
+ relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx;
+ num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
+ move16();
+ num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
+ move16();
+ num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
+ move16();
+ }
+ ELSE
+ {
+ relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_fx;
+ relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_fx;
+ relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_fx;
+ num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
+ move16();
+ num_pitch_poses = 1;
+ move16();
+ num_roll_poses = 1;
+ move16();
+ }
+ }
+
+ pMultiBinPoseData->num_poses = add( add( num_yaw_poses, num_pitch_poses ), add( num_roll_poses, 1 ) );
+ assert( LE_16( pMultiBinPoseData->num_poses, MAX_HEAD_ROT_POSES ) );
+
+ FOR( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] = relative_yaw_angles[pos_idx];
+ move32();
+ }
+
+ FOR( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx];
+ move32();
+ }
+
+ FOR( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx];
+ move32();
+ }
+ pMultiBinPoseData->dof = pSplit_rend_config->dof;
+ move16();
+ pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode;
+ move16();
+ pMultiBinPoseData->rot_axis = rot_axis;
+ move32();
+ pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode;
+ move32();
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * Function isar_renderSplitUpdateNoCorrectionPoseData()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_renderSplitUpdateNoCorrectionPoseData(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ pMultiBinPoseData->num_poses = 1;
+ move16();
+ assert( pSplit_rend_config->dof == 0 );
+ pMultiBinPoseData->dof = pSplit_rend_config->dof;
+ move16();
+ assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE );
+ pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode;
+ move32();
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function isar_init_multi_bin_pose_data()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+void isar_init_multi_bin_pose_data_fx(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ Word16 pos_idx;
+
+ FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
+ move32();
+ }
+ pMultiBinPoseData->num_poses = 1;
+ move16();
+ pMultiBinPoseData->dof = 3;
+ move16();
+ pMultiBinPoseData->hq_mode = 0;
+ move16();
+ pMultiBinPoseData->rot_axis = DEFAULT_AXIS;
+ move32();
+
+ return;
+}
+
+/* Copy for encoder, to be removed */
+void isar_init_multi_bin_pose_data_fx_enc(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ Word16 pos_idx;
+
+ FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0;
+ move32();
+ pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0;
+ move32();
+ }
+ pMultiBinPoseData->num_poses = 1;
+ move16();
+ pMultiBinPoseData->dof = 3;
+ move16();
+ pMultiBinPoseData->hq_mode = 0;
+ move16();
+ pMultiBinPoseData->rot_axis = DEFAULT_AXIS;
+ move32();
+
+ return;
+}
+void isar_init_multi_bin_pose_data(
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
+{
+ int16_t pos_idx;
+
+ for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ )
+ {
+ pMultiBinPoseData->relative_head_poses[pos_idx][0] = 0.0f;
+ pMultiBinPoseData->relative_head_poses[pos_idx][1] = 0.0f;
+ pMultiBinPoseData->relative_head_poses[pos_idx][2] = 0.0f;
+ }
+ pMultiBinPoseData->num_poses = 1;
+ pMultiBinPoseData->dof = 3;
+ pMultiBinPoseData->hq_mode = 0;
+ pMultiBinPoseData->rot_axis = DEFAULT_AXIS;
+
+ return;
+}
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ivas_error isar_framesize_to_ms(
+ const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
+ int16_t *ms /* o : frame size in ms */
+)
+{
+ switch ( frame_size )
+ {
+ case IVAS_RENDER_FRAMESIZE_5MS:
+ *ms = 5;
+ break;
+ case IVAS_RENDER_FRAMESIZE_10MS:
+ *ms = 10;
+ break;
+ case IVAS_RENDER_FRAMESIZE_20MS:
+ *ms = 20;
+ break;
+ default:
+ return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" );
+ }
+
+ return IVAS_ERR_OK;
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Function isar_split_rend_choose_default_codec()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error isar_split_rend_choose_default_codec(
+ ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */
+#endif
+ Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */
+ const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */
+ const Word16 pcm_out_flag, /* i : flag to indicate PCM output */
+ const Word16 num_subframes /* i : number of subframes */
+)
+{
+ IF( EQ_16( pcm_out_flag, 0 ) )
+ {
+ IF( EQ_32( *pCodec, ISAR_SPLIT_REND_CODEC_DEFAULT ) )
+ {
+ *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS;
+ move32();
+ }
+ }
+ ELSE
+ {
+ *pCodec = ISAR_SPLIT_REND_CODEC_NONE;
+ move32();
+ }
+
+ IF( EQ_16( *pCodec_frame_size_ms, 0 ) ) /* codec frame size hasn't been set yet - use default for current configuration */
+ {
+ SWITCH( *pCodec )
+ {
+ case ISAR_SPLIT_REND_CODEC_LCLD:
+ *pCodec_frame_size_ms = DEPR_i_mult( num_subframes, 5 );
+ BREAK;
+ case ISAR_SPLIT_REND_CODEC_LC3PLUS:
+ case ISAR_SPLIT_REND_CODEC_NONE:
+ *pCodec_frame_size_ms = 5;
+ move16();
+ BREAK;
+ default:
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" );
+ }
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ IF( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */
+ {
+ *pIsar_frame_size_ms = 20;
+ }
+#endif
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * Function get_bit()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+Word32 get_bit(
+ const Word32 state,
+ const Word32 bit_id )
+{
+ return L_and( state, ( L_shl( 1, (Word16) bit_id ) ) );
+}
+
+void set16_fx(
+ Word16 y[], /* i/o: Vector to set */
+ const Word16 a, /* i : Value to set the vector to */
+ const Word16 N /* i : Lenght of the vector */
+)
+{
+ Word16 i;
+
+ for ( i = 0; i < N; i++ )
+ {
+ y[i] = a;
+ }
+
+ return;
+}
+
+void set32_fx(
+ Word32 y[], /* i/o: Vector to set */
+ const Word32 a, /* i : Value to set the vector to */
+ const Word16 N /* i : Length of the vector */
+)
+{
+ Word16 i;
+
+ FOR( i = 0; i < N; i++ )
+ {
+ y[i] = a;
+ move32();
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * ceil_log_2()
+ *
+ * calculates ceil(log2(val))
+ *-------------------------------------------------------------------*/
+
+Word16 ceil_log_2(
+ UWord64 val )
+{
+
+ IF( val <= 0 )
+ {
+ assert( 0 );
+ }
+ return val <= 1 ? 0 : val <= 2 ? 1
+ : val <= 4 ? 2
+ : val <= 8 ? 3
+ : val <= 16 ? 4
+ : val <= 32 ? 5
+ : val <= 64 ? 6
+ : val <= 128 ? 7
+ : val <= 256 ? 8
+ : val <= 512 ? 9
+ : val <= 1024 ? 10
+ : val <= 2048 ? 11
+ : val <= 4096 ? 12
+ : val <= 8192 ? 13
+ : val <= 16384 ? 14
+ : val <= 32768 ? 15
+ : val <= 65536 ? 16
+ : val <= 131072 ? 17
+ : val <= 262144 ? 18
+ : val <= 524288 ? 19
+ : val <= 1048576 ? 20
+ : val <= 2097152 ? 21
+ : val <= 4194304 ? 22
+ : val <= 8388608 ? 23
+ : val <= 16777216 ? 24
+ : val <= 33554432 ? 25
+ : val <= 67108864 ? 26
+ : val <= 134217728 ? 27
+ : val <= 268435456 ? 28
+ : val <= 536870912 ? 29
+ : val <= 1073741824 ? 30
+ : val <= 2147483648 ? 31
+ : val <= 4294967296 ? 32
+ : val <= 8589934592 ? 33
+ : val <= 17179869184 ? 34
+ : val <= 34359738368 ? 35
+ : val <= 68719476736 ? 36
+ : val <= 137438953472 ? 37
+ : val <= 274877906944 ? 38
+ : val <= 549755813888 ? 39
+ : val <= 1099511627776 ? 40
+ : val <= 2199023255552 ? 41
+ : val <= 4398046511104 ? 42
+ : val <= 8796093022208 ? 43
+ : val <= 17592186044416 ? 44
+ : val <= 35184372088832 ? 45
+ : val <= 70368744177664 ? 46
+ : val <= 140737488355328 ? 47
+ : val <= 281474976710656 ? 48
+ : val <= 562949953421312 ? 49
+ : val <= 1125899906842624 ? 50
+ : val <= 2251799813685248 ? 51
+ : val <= 4503599627370496 ? 52
+ : val <= 9007199254740992 ? 53
+ : val <= 18014398509481984 ? 54
+ : val <= 36028797018963968 ? 55
+ : val <= 72057594037927936 ? 56
+ : val <= 144115188075855872 ? 57
+ : val <= 288230376151711744 ? 58
+ : val <= 576460752303423488 ? 59
+ : val <= 1152921504606846976 ? 60
+ : val <= 2305843009213693952 ? 61
+ : val <= 4611686018427387904 ? 62
+ : val <= 9223372036854775807 ? 63
+ : 64;
+}
+#endif
diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h
new file mode 100644
index 0000000000000000000000000000000000000000..e94d23e18dc90d09a5d71f84d3a8a670c2bfb540
--- /dev/null
+++ b/lib_isar/isar_stat.h
@@ -0,0 +1,267 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef ISAR_STAT_H
+#define ISAR_STAT_H
+
+
+#include
+#include "options.h"
+#include "stat_com.h"
+#include "ivas_stat_com.h"
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+#include "isar_lcld_prot.h"
+#include "isar_lc3plus_enc.h"
+#include "isar_lc3plus_dec.h"
+#include "isar_cnst.h"
+
+
+/*-------------------------------------------------------------------*
+ * ISAR post rend constants
+ *-------------------------------------------------------------------*/
+
+#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 )
+#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
+#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
+#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
+
+/*-------------------------------------------------------------------*
+ * ISAR post rend structs
+ *-------------------------------------------------------------------*/
+
+typedef struct
+{
+ int8_t headRotEnabled;
+ IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
+ IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word32 crossfade_fx[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
+ ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
+
+} ISAR_POST_REND_HeadRotData;
+
+typedef struct
+{
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS];
+#else
+ HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
+#endif
+ HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS];
+
+} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE;
+
+typedef struct isar_split_rend_huffman_cfg_t
+{
+ const int32_t *codebook;
+ int16_t min_len;
+ int16_t max_len;
+ int16_t sym_len;
+
+} isar_split_rend_huffman_cfg_t;
+
+typedef struct isar_binaural_head_rot_split_rendering_huff_struct
+{
+ isar_split_rend_huffman_cfg_t pred[2];
+ int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS];
+ int16_t pred_base2_code_len[2];
+ isar_split_rend_huffman_cfg_t pred_roll;
+ int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS];
+ int16_t pred_roll_base2_code_len;
+ isar_split_rend_huffman_cfg_t gd;
+ int16_t gd_base2_code_len;
+ int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
+ isar_split_rend_huffman_cfg_t p_gd;
+ int16_t p_gd_base2_code_len;
+ int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
+ isar_split_rend_huffman_cfg_t p_gd_diff;
+ int16_t p_gd_diff_base2_code_len;
+ int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
+
+} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE;
+
+/* binaural split rendering head rotation data structure */
+typedef struct isar_binaural_head_rot_split_rendering_md_struct
+{
+ Word32 pred_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */
+ Word16 exp_pred_mat_re;
+ Word32 pred_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */
+ Word16 exp_pred_mat_im;
+#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
+ Word32 pred_mat_re2[BINAURAL_CHANNELS];
+ Word16 exp_pred_mat_re2;
+#endif
+ Word32 gd_fx; /* Q25 */
+ Word32 gd2_fx; /* Q25 */
+ Word16 exp_gd;
+ Word16 exp_gd2;
+ int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ int16_t gd_idx;
+ int16_t gd2_idx;
+
+} ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE;
+typedef struct isar_binaural_head_rot_split_pre_rendering_struct
+{
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS];
+ Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
+ ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS];
+#endif
+
+#ifdef SPLIT_POSE_CORRECTION_DEBUG
+ BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend;
+#endif
+
+} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE;
+/*----------------------------------------------------------------------------------*
+ * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...)
+ *----------------------------------------------------------------------------------*/
+
+typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct
+{
+ void *pLcld_enc;
+ Word16 iChannels;
+ LCLDEncoder *psLCLDEncoder;
+ Word32 ***pppfLCLDReal_fx;
+ Word32 ***pppfLCLDImag_fx;
+#ifdef CLDFB_DEBUG
+ FILE *cldfbIn;
+ int16_t numFrame;
+#endif
+ Word16 iNumIterations;
+ Word16 iNumBlocks;
+
+} ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE;
+
+typedef struct
+{
+ Word32 Cldfb_Prev_BinReal_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_Prev_BinImag_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX];
+ Word16 Q_Prev_Bin_fx;
+ Word32 xf_bet_fx[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF];
+
+} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE;
+typedef struct
+{
+ ISAR_CLDFB_PLC CldfbPLC_state;
+ Word16 prev_bfi;
+ Word16 bf_count;
+ Word16 iNumSubSets;
+
+} ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE;
+typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct
+{
+ void *pLcld_dec;
+ Word32 iChannels;
+ LCLDDecoder *psLCLDDecoder;
+ Word32 ***pppfDecLCLDReal_fx;
+ Word32 ***pppfDecLCLDImag_fx;
+#ifdef CLDFB_DEBUG
+ FILE *cldfbOut;
+ int16_t numFrame;
+#endif
+ ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC;
+
+ Word16 iNumBlocks;
+ Word16 iNumIterations;
+
+} ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE;
+typedef struct isar_binaural_head_rot_split_post_rendering_struct
+{
+ ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS];
+ IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES];
+ int16_t low_Res;
+
+ float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q31 */
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
+ ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ Word32 mixer_mat_re_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mixer_mat_im_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 gd_mem_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS];
+#else
+ Word32 mixer_mat_re_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 mixer_mat_im_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
+ Word32 gd_mem_fx[1][MAX_SPLIT_REND_MD_BANDS];
+#endif
+ int16_t cf_flag;
+ HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS];
+ HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS];
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS];
+#endif
+
+} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE;
+
+typedef struct
+{
+ int16_t num_poses;
+ float relative_head_poses[MAX_HEAD_ROT_POSES][3];
+ Word32 relative_head_poses_fx[MAX_HEAD_ROT_POSES][3]; /* Q22 */
+ int16_t dof;
+ int16_t hq_mode;
+ ISAR_SPLIT_REND_ROT_AXIS rot_axis;
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode;
+
+} MULTI_BIN_REND_POSE_DATA;
+
+typedef struct
+{
+ MULTI_BIN_REND_POSE_DATA multiBinPoseData;
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend;
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec;
+ int16_t first_good_frame_received;
+ ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec;
+
+} ISAR_SPLIT_POST_REND_WRAPPER;
+
+
+typedef struct
+{
+ MULTI_BIN_REND_POSE_DATA multiBinPoseData;
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend;
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc;
+ CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles;
+ ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc;
+ float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */
+ Word32 *lc3plusDelayBuffers_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */
+ Word16 lc3plusDelayBuffers_q;
+ Word32 lc3plusDelaySamples;
+} SPLIT_REND_WRAPPER;
+
+#endif
+
+#endif /* ISAR_STAT_H */
diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c
new file mode 100644
index 0000000000000000000000000000000000000000..178718a602e5ee82b39f07c7567ca8ec66ca450c
--- /dev/null
+++ b/lib_isar/lib_isar_post_rend.c
@@ -0,0 +1,1913 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+
+#include "options.h"
+#include "lib_isar_post_rend.h"
+#include "isar_stat.h"
+#include "isar_prot.h"
+#include "prot.h"
+#include "ivas_prot.h"
+#include "prot_fx2.h"
+#ifndef SPLIT_REND_WITH_HEAD_ROT
+
+int32_t ISAR_POST_REND_void_func( void )
+{
+ return 0;
+}
+
+#else
+
+#include "ivas_prot_rend.h"
+#include
+#include
+#include "wmc_auto.h"
+#include "prot_fx2.h"
+
+
+/*-------------------------------------------------------------------*
+ * Local constants
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Local types
+ *-------------------------------------------------------------------*/
+
+/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */
+typedef struct
+{
+ EFAP_HANDLE hEfap;
+ AUDIO_CONFIG speakerConfig;
+ const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */
+} EFAP_WRAPPER;
+
+/* Lightweight helper struct that gathers all information required for rendering
+ * any config to any other config. Used to simplify signatures of rendering functions.
+ *
+ * This struct should store ONLY CONST POINTERS to data existing elsewhere.
+ * Storing pointers instead of data itself ensures that no additional updates
+ * are required when any of these are changed in the renderer. Making the pointers
+ * const ensures that this data is only read, but not modified by the rendering functions. */
+typedef struct
+{
+ const int32_t *pOutSampleRate;
+ const AUDIO_CONFIG *pOutConfig;
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const LSSETUP_CUSTOM_STRUCT *pCustomLsOut;
+ const EFAP_WRAPPER *pEfapOutWrapper;
+#endif
+ const ISAR_POST_REND_HeadRotData *pHeadRotData;
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const RENDER_CONFIG_HANDLE *hhRendererConfig;
+#endif
+ const int16_t *pSplitRendBFI;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig;
+#endif
+} rendering_context;
+
+/* Common base for input structs */
+typedef struct
+{
+ AUDIO_CONFIG inConfig;
+ ISAR_POST_REND_InputId id;
+ IVAS_REND_AudioBuffer inputBuffer;
+ Word32 gain_fx; /* Linear, not in dB */
+ rendering_context ctx;
+ int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */
+} input_base;
+
+typedef struct
+{
+ input_base base;
+ ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper;
+ Word32 *bufferData_fx;
+ int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */
+ ISAR_POST_REND_BitstreamBuffer *hBits;
+} input_split_post_rend;
+
+struct ISAR_POST_REND
+{
+ int32_t sampleRateOut;
+
+ IVAS_LIMITER_HANDLE hLimiter;
+#ifdef DEBUGGING
+ int32_t numClipping; /* Counter of clipped output samples */
+#endif
+
+ input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS];
+
+ AUDIO_CONFIG inputConfig;
+ AUDIO_CONFIG outputConfig;
+
+ ISAR_POST_REND_HeadRotData headRotData;
+ int16_t splitRendBFI;
+
+ int8_t rendererConfigEnabled;
+ ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig;
+
+ int16_t num_subframes;
+};
+
+/*-------------------------------------------------------------------*
+ * getAudioConfigType()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ISAR_POST_REND_AudioConfigType isar_getAudioConfigType(
+ const AUDIO_CONFIG config )
+{
+ ISAR_POST_REND_AudioConfigType type;
+
+ SWITCH( config )
+ {
+ case IVAS_AUDIO_CONFIG_BINAURAL:
+ case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM:
+ case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED:
+ type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL;
+ BREAK;
+ default:
+ type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN;
+ BREAK;
+ }
+
+ return type;
+}
+
+/*-------------------------------------------------------------------*
+ * Local function prototypes
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Local functions
+ *-------------------------------------------------------------------*/
+static ivas_error allocateInputBaseBufferData_fx(
+ Word32 **data,
+ const Word16 data_size )
+{
+ *data = (Word32 *) malloc( data_size * sizeof( Word32 ) );
+ IF( *data == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" );
+ }
+
+ return IVAS_ERR_OK;
+}
+static void freeInputBaseBufferData_fx(
+ Word32 **data )
+{
+ IF( *data != NULL )
+ {
+ free( *data );
+ *data = NULL;
+ }
+
+ return;
+}
+
+static IVAS_QUATERNION quaternionInit(
+ void )
+{
+ IVAS_QUATERNION q;
+ q.w_fx = ONE_IN_Q22;
+ q.x_fx = q.y_fx = q.z_fx = 0;
+ return q;
+}
+
+static void convertBitsBufferToInternalBitsBuff(
+ const ISAR_POST_REND_BitstreamBuffer outBits,
+ ISAR_SPLIT_REND_BITS_HANDLE hBits )
+{
+ hBits->bits_buf = outBits.bits;
+ hBits->bits_read = outBits.config.bitsRead;
+ hBits->bits_written = outBits.config.bitsWritten;
+ hBits->buf_len = outBits.config.bufLenInBytes;
+ hBits->codec = outBits.config.codec;
+ hBits->pose_correction = outBits.config.poseCorrection;
+ hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms;
+ hBits->lc3plus_highres = outBits.config.lc3plusHighRes;
+#endif
+
+ return;
+}
+
+static void convertInternalBitsBuffToBitsBuffer(
+ ISAR_POST_REND_BitstreamBuffer *hOutBits,
+ const ISAR_SPLIT_REND_BITS_DATA bits )
+{
+ hOutBits->bits = bits.bits_buf;
+ hOutBits->config.bitsRead = bits.bits_read;
+ hOutBits->config.bitsWritten = bits.bits_written;
+ hOutBits->config.bufLenInBytes = bits.buf_len;
+ hOutBits->config.codec = bits.codec;
+ hOutBits->config.poseCorrection = bits.pose_correction;
+ hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms;
+ hOutBits->config.lc3plusHighRes = bits.lc3plus_highres;
+#endif
+
+ return;
+}
+
+static void copyBufferTo2dArray_fx(
+ const IVAS_REND_AudioBuffer buffer,
+ Word32 array[][L_FRAME48k] )
+{
+ UWord32 smplIdx;
+ UWord32 chnlIdx;
+ const Word32 *readPtr;
+
+ assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" );
+ readPtr = buffer.data_fx;
+
+ FOR( chnlIdx = 0; chnlIdx < (UWord32) buffer.config.numChannels; ++chnlIdx )
+ {
+ FOR( smplIdx = 0; smplIdx < (UWord32) buffer.config.numSamplesPerChannel; ++smplIdx )
+ {
+ array[chnlIdx][smplIdx] = *readPtr++;
+ }
+ }
+
+ return;
+}
+
+static void accumulate2dArrayToBuffer_fx(
+ Word32 array[][L_FRAME48k],
+ Word16 Q_out[][BINAURAL_CHANNELS],
+ Word16 Q_max,
+ const IVAS_REND_AudioBuffer *buffer,
+ Word16 num_subframes,
+ Word16 subframe_length )
+{
+ Word16 smplIdx, chnlIdx;
+ Word32 *writePtr;
+
+ writePtr = buffer->data_fx;
+ FOR( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx )
+ {
+ FOR( Word16 sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ FOR( smplIdx = 0; smplIdx < subframe_length; ++smplIdx )
+ {
+ //*writePtr++ += (float) array[chnlIdx][( sf_idx * subframe_length ) + smplIdx] / powf( 2, Q_out[sf_idx][chnlIdx] );
+ *writePtr++ += L_shl( array[chnlIdx][( sf_idx * subframe_length ) + smplIdx], sub( Q_max, Q_out[sf_idx][chnlIdx] ) );
+ }
+ }
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * limitRendererOutput()
+ *
+ * In-place saturation control for multichannel buffers with adaptive release time
+ *-------------------------------------------------------------------*/
+
+#ifndef DISABLE_LIMITER
+/*! r: number of clipped output samples */
+static Word32 limitRendererOutput_fx(
+ IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
+ Word32 *output, /* i/o: I/O buffer */
+ const Word16 output_frame, /* i : number of samples per channel in the buffer */
+ const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */
+ Word16 q_factor ) /* i : q factor of output samples */
+{
+ Word16 i;
+ Word32 **channels;
+ Word16 num_channels;
+ Word32 numClipping = 0;
+
+ /* return early if given bad parameters */
+ IF( hLimiter == NULL || output == NULL || output_frame <= 0 )
+ {
+ return 0;
+ }
+
+ channels = hLimiter->channel_ptrs_fx;
+ num_channels = hLimiter->num_channels;
+
+ FOR( i = 0; i < num_channels; ++i )
+ {
+ channels[i] = output + i * output_frame;
+ }
+
+ limiter_process_fx( hLimiter, output_frame, threshold, 0, NULL, q_factor );
+
+ /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */
+ FOR( i = 0; i < output_frame * num_channels; ++i )
+ {
+
+ output[i] = min( max( L_shl( INT16_MIN, q_factor ), output[i] ), L_shl( INT16_MAX, q_factor ) );
+ }
+
+ return numClipping;
+}
+
+#endif
+
+
+/*-------------------------------------------------------------------*
+ * validateOutputSampleRate()
+ *
+ *
+ *-------------------------------------------------------------------*/
+static ivas_error validateOutputSampleRate(
+ const Word32 sampleRate,
+ const AUDIO_CONFIG outConfig )
+{
+ IF( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && NE_32( sampleRate, 48000 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." );
+ }
+ ELSE
+ {
+ /* Otherwise rendering to binaural, support the same set as IVAS decoder */
+ SWITCH( sampleRate )
+ {
+ case 8000:
+ case 16000:
+ case 32000:
+ case 48000:
+ return IVAS_ERR_OK;
+ }
+
+ return IVAS_ERR_INVALID_SAMPLING_RATE;
+ }
+}
+
+/*-------------------------------------------------------------------*
+ * Local functions
+ *-------------------------------------------------------------------*/
+static ivas_error initLimiter(
+ IVAS_LIMITER_HANDLE *phLimiter,
+ const Word16 numChannels,
+ const Word32 sampleRate )
+{
+ ivas_error error;
+
+ /* If re-initializing with unchanged values, return early */
+ IF( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate )
+ {
+ return IVAS_ERR_OK;
+ }
+
+ /* Support re-init: close if already allocated */
+ IF( *phLimiter != NULL )
+ {
+ ivas_limiter_close_splitRend( phLimiter );
+ }
+
+ IF( ( error = ivas_limiter_open_splitRend( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+static ivas_error initHeadRotation(
+ ISAR_POST_REND_HANDLE hIvasRend )
+{
+ Word16 i, crossfade_len;
+ Word32 tmp;
+
+ /* Head rotation is enabled by default */
+ hIvasRend->headRotData.headRotEnabled = 1;
+
+ /* Initialize 5ms crossfade */
+ crossfade_len = 240 /*L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES*/;
+ tmp = 8985287 /*1.f / ( crossfade_len - 1 )*/;
+ FOR( i = 0; i < crossfade_len; i++ )
+ {
+ hIvasRend->headRotData.crossfade_fx[i] = W_extract_l( W_mult0_32_32( i, tmp ) );
+ }
+
+ /* Initialize with unit quaternions */
+ FOR( i = 0; i < hIvasRend->num_subframes; ++i )
+ {
+ hIvasRend->headRotData.headPositions[i] = quaternionInit();
+ }
+
+ hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS;
+
+ return IVAS_ERR_OK;
+}
+static void initRendInputBase_fx(
+ input_base *inputBase,
+ const AUDIO_CONFIG inConfig,
+ const IVAS_REND_InputId id,
+ const rendering_context rendCtx,
+ Word32 *dataBuf,
+ const Word16 dataBufSize )
+{
+ inputBase->inConfig = inConfig;
+ inputBase->id = id;
+ inputBase->gain_fx = MAX_32;
+ inputBase->ctx = rendCtx;
+ inputBase->numNewSamplesPerChannel = 0;
+
+ inputBase->inputBuffer.config.numSamplesPerChannel = 0;
+ inputBase->inputBuffer.config.numChannels = 0;
+ inputBase->inputBuffer.data_fx = dataBuf;
+ IF( inputBase->inputBuffer.data_fx != NULL )
+ {
+ set_l( inputBase->inputBuffer.data_fx, 0, dataBufSize );
+ }
+
+ return;
+}
+
+static rendering_context getRendCtx(
+ ISAR_POST_REND_HANDLE hIvasRend )
+{
+ rendering_context ctx;
+
+ /* Note: when refactoring this, always take the ADDRESS of a member of the
+ * renderer struct, so that the context stores a POINTER to the member, even
+ * if the member is a pointer or handle itself. */
+ ctx.pOutConfig = &hIvasRend->outputConfig;
+ ctx.pOutSampleRate = &hIvasRend->sampleRateOut;
+ ctx.pHeadRotData = &hIvasRend->headRotData;
+ ctx.pSplitRendBFI = &hIvasRend->splitRendBFI;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig;
+#endif
+
+ return ctx;
+}
+
+
+static ivas_error getRendInputNumChannels(
+ const void *rendInput,
+ Word16 *numInChannels )
+{
+ /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba).
+ Assumptions: - input_base is always the first member in the input struct */
+ (void) rendInput;
+
+ *numInChannels = 2;
+
+ return IVAS_ERR_OK;
+}
+
+static ivas_error updateSplitPostRendPanGains(
+ input_split_post_rend *inputSplitPostRend,
+ const AUDIO_CONFIG outConfig,
+ ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ int16_t num_subframes
+#endif
+)
+{
+ ivas_error error;
+ rendering_context rendCtx;
+ LC3PLUS_CONFIG config;
+ Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame;
+
+ (void) outConfig;
+
+ rendCtx = inputSplitPostRend->base.ctx;
+ isar_renderSplitGetMultiBinPoseData_fx( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis );
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 );
+#endif
+ config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000;
+#else
+ IF( NE_16( num_subframes, MAX_PARAM_SPATIAL_SUBFRAMES ) )
+ {
+ IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
+ {
+ config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000;
+ }
+ ELSE
+ {
+ config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000;
+ }
+ iNumLCLDIterationsPerFrame = 1;
+ }
+ ELSE
+ {
+ config.ivas_frame_duration_us = 20000;
+ }
+#endif
+
+ IF( GT_16( hRendCfg->codec_frame_size_ms, 0 ) )
+ {
+ iNumLCLDIterationsPerFrame = (Word16) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms );
+ iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame );
+ iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20;
+ }
+ ELSE
+ {
+ iNumLCLDIterationsPerFrame = 1;
+ iNumBlocksPerFrame = CLDFB_NO_COL_MAX;
+ }
+
+ config.channels = BINAURAL_CHANNELS;
+ config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate;
+
+ IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ IF( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ ELSE IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
+ {
+ IF( ( error = ISAR_LC3PLUS_DEC_Open( config,
+ &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ IF( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+static ivas_error setRendInputActiveSplitPostRend(
+ void *input,
+ const AUDIO_CONFIG inConfig,
+ const IVAS_REND_InputId id,
+ ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ const int16_t num_subframes
+#endif
+)
+{
+ ivas_error error;
+ rendering_context rendCtx;
+ AUDIO_CONFIG outConfig;
+ input_split_post_rend *inputSplitPostRend;
+
+ inputSplitPostRend = (input_split_post_rend *) input;
+ rendCtx = inputSplitPostRend->base.ctx;
+ outConfig = *rendCtx.pOutConfig;
+
+ IF( ( error = allocateInputBaseBufferData_fx( &inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ initRendInputBase_fx( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH );
+
+ inputSplitPostRend->numCachedSamples = 0;
+
+ if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ num_subframes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+static void clearInputSplitRend(
+ input_split_post_rend *inputSplitRend )
+{
+ rendering_context rendCtx;
+
+ rendCtx = inputSplitRend->base.ctx;
+
+ freeInputBaseBufferData_fx( &inputSplitRend->bufferData_fx );
+
+ initRendInputBase_fx( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 );
+
+ IF( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL )
+ {
+ isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend );
+ }
+
+ IF( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL )
+ {
+ isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec );
+ }
+
+ IF( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL )
+ {
+ ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec );
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ISAR_POST_REND_open()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_open(
+ ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */
+ const Word32 outputSampleRate, /* i : output sampling rate */
+ const AUDIO_CONFIG outConfig, /* i : output audio config */
+ const bool asHrtfBinary, /* i : load hrtf binary file */
+ const Word16 nonDiegeticPan, /* i : non-diegetic object flag */
+ const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */
+ const Word16 num_subframes ) /* i : number of subframes */
+{
+ Word16 i;
+ ISAR_POST_REND_HANDLE hIvasRend;
+ ivas_error error;
+ Word16 numOutChannels;
+
+ (void) asHrtfBinary;
+ (void) nonDiegeticPan;
+ (void) nonDiegeticPanGain;
+
+ /* Validate function arguments */
+ IF( phIvasRend == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ IF( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) );
+ IF( *phIvasRend == NULL )
+ {
+ return IVAS_ERR_FAILED_ALLOC;
+ }
+
+ hIvasRend = *phIvasRend;
+ hIvasRend->sampleRateOut = outputSampleRate;
+ hIvasRend->outputConfig = outConfig;
+ hIvasRend->hLimiter = NULL;
+ hIvasRend->num_subframes = 1;
+#ifdef DEBUGGING
+ hIvasRend->numClipping = 0;
+#endif
+ hIvasRend->num_subframes = num_subframes;
+
+ /* Initialize limiter */
+ IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Initialize headrotation data */
+ IF( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Initialize inputs */
+
+ FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
+ {
+ initRendInputBase_fx( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 );
+
+ isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper );
+
+ hIvasRend->splitRendBFI = 0;
+ hIvasRend->inputsSplitPost[i].bufferData_fx = NULL;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_NumOutChannels()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_NumOutChannels(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
+ Word16 *numOutChannels /* o : number of output channels */
+)
+{
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || numOutChannels == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ *numOutChannels = 2;
+
+ return IVAS_ERR_OK;
+}
+
+static IVAS_REND_InputId makeInputId(
+ AUDIO_CONFIG config,
+ const Word32 inputIndex )
+{
+ /* Put config type in second byte (from LSB), put index + 1 in first byte
+ *
+ * Index is incremented here so that a valid ID can never be 0. */
+ return (IVAS_REND_InputId) ( ( ( (UWord32) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) );
+}
+
+static ivas_error getInputById(
+ ISAR_POST_REND_HANDLE hIvasRend,
+ const IVAS_REND_InputId inputId,
+ void **ppInput )
+{
+ Word32 inputIndex;
+ IVAS_REND_AudioConfigType configType;
+ input_base *pInputBase;
+
+ /* Reverse makeInputId() */
+ inputIndex = ( inputId & 0xFF ) - 1;
+ configType = ( inputId & 0xFF00 ) >> 8;
+
+ /* Validate values derived from input ID */
+ IF( inputIndex < 0 )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+ SWITCH( configType )
+ {
+ case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
+ if ( inputIndex > RENDERER_MAX_BIN_INPUTS )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+ pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
+ BREAK;
+ default:
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+
+ /* Ensure input ID matches and that input is active */
+ IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+
+ /* Validation done, set value via output parameter */
+ *ppInput = pInputBase;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_SetInputGain()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_SetInputGain(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ const Word32 gain /* i : linear gain (not in dB) */
+)
+{
+ input_base *inputBase;
+ ivas_error error;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
+ {
+ printf( "Hoo\n" );
+ return error;
+ }
+
+ inputBase->gain_fx = gain;
+
+ return IVAS_ERR_OK;
+}
+
+static ivas_error getConstInputById(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend,
+ const ISAR_POST_REND_InputId inputId,
+ const void **ppInput )
+{
+ Word32 inputIndex;
+ IVAS_REND_AudioConfigType configType;
+ const input_base *pInputBase;
+
+ /* Reverse makeInputId() */
+ inputIndex = ( inputId & 0xFF ) - 1;
+ configType = ( inputId & 0xFF00 ) >> 8;
+
+ /* Validate values derived from input ID */
+ IF( inputIndex < 0 )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+ SWITCH( configType )
+ {
+ case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
+ IF( inputIndex > RENDERER_MAX_BIN_INPUTS )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+ pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
+ BREAK;
+ default:
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+
+ /* Ensure input ID matches and that input is active */
+ IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
+ {
+ return IVAS_ERR_INVALID_INPUT_ID;
+ }
+
+ /* Validation done, set value via output parameter */
+ *ppInput = pInputBase;
+
+ return IVAS_ERR_OK;
+}
+
+static ivas_error findFreeInputSlot(
+ const void *inputs,
+ const Word32 inputStructSize,
+ const Word32 maxInputs,
+ Word32 *inputIndex )
+{
+ /* Using a void pointer and a separately provided size is a hack for this function
+ to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa).
+ Assumptions:
+ - input_base is always the first member in the input struct
+ - provided size is correct
+ */
+
+ Word32 i;
+ bool canAddInput;
+ const UWord8 *pByte;
+ const input_base *pInputBase;
+
+ canAddInput = false;
+ pByte = inputs;
+ /* Find first unused input in array */
+ FOR( i = 0; i < maxInputs; ++i )
+ {
+ pInputBase = (const input_base *) pByte;
+
+ IF( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
+ {
+ *inputIndex = i;
+ canAddInput = true;
+ BREAK;
+ }
+ pByte += inputStructSize;
+ }
+
+ IF( !canAddInput )
+ {
+ return IVAS_ERR_TOO_MANY_INPUTS;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_AddInput()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_AddInput(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */
+ ISAR_POST_REND_InputId *inputId /* o : ID of the new input */
+)
+{
+ ivas_error error;
+ Word32 maxNumInputsOfType;
+ void *inputsArray;
+ Word32 inputStructSize;
+ ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA *
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ int16_t
+#endif
+ );
+ Word32 inputIndex;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || inputId == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ SWITCH( isar_getAudioConfigType( inConfig ) )
+ {
+ case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
+ maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS;
+ inputsArray = hIvasRend->inputsSplitPost;
+ inputStructSize = sizeof( *hIvasRend->inputsSplitPost );
+ activateInput = setRendInputActiveSplitPostRend;
+ BREAK;
+ default:
+ return IVAS_ERR_INVALID_INPUT_FORMAT;
+ }
+
+ /* Find first free input in array corresponding to input type */
+ IF( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ *inputId = makeInputId( inConfig, inputIndex );
+ if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ hIvasRend->num_subframes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_GetInputNumChannels()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_GetInputNumChannels(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ Word16 *numChannels /* o : number of channels of the input */
+)
+{
+ ivas_error error;
+ const input_base *pInput;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || numChannels == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ IF( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_GetDelay()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_GetDelay(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */
+ Word16 *nSamples, /* o : Renderer delay in samples */
+ Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */
+)
+{
+ Word16 i;
+ Word32 latency_ns;
+ Word32 max_latency_ns;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || nSamples == NULL || timeScale == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ *timeScale = hIvasRend->sampleRateOut;
+ *nSamples = 0;
+ max_latency_ns = 0;
+
+ /* Compute the maximum delay across all inputs */
+ FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ){
+ IF( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ){
+ latency_ns = 0;
+ IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL )
+ {
+ int32_t lc3plusDelaySamples;
+ ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples );
+ latency_ns = (Word32) ( ( ( (Word64) lc3plusDelaySamples * 1000000000 ) + ( *timeScale / 2 ) ) / *timeScale );
+ }
+ IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ latency_ns += IVAS_FB_DEC_DELAY_NS;
+ }
+ ELSE IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL )
+ {
+ latency_ns += IVAS_FB_DEC_DELAY_NS;
+ }
+ max_latency_ns = max( max_latency_ns, latency_ns );
+}
+}
+
+*nSamples = (Word16) ( ( ( (Word64) max_latency_ns * *timeScale ) + 500000000 ) / 1000000000 );
+
+return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_FeedInputAudio()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_FeedInputAudio(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */
+)
+{
+ ivas_error error;
+ input_base *inputBase;
+ Word16 numInputChannels;
+ Word16 cldfb2tdSampleFact;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || inputAudio.data_fx == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1;
+
+ IF( LE_16( inputAudio.config.numSamplesPerChannel, 0 ) || ( LT_16( MAX_BUFFER_LENGTH_PER_CHANNEL, inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 0 ) ) ||
+ ( LT_16( DEPR_i_mult( MAX_BUFFER_LENGTH_PER_CHANNEL, cldfb2tdSampleFact ), inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 1 ) ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" );
+ }
+
+ IF( LE_16( inputAudio.config.numChannels, 0 ) || LT_16( MAX_INPUT_CHANNELS, inputAudio.config.numChannels ) )
+ {
+ return IVAS_ERR_WRONG_NUM_CHANNELS;
+ }
+
+ IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL &&
+ hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED &&
+ hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM &&
+ ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" );
+ }
+
+ IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
+ {
+ printf( "Foo\n" );
+ return error;
+ }
+
+ IF( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( numInputChannels != inputAudio.config.numChannels )
+ {
+ return IVAS_ERR_WRONG_NUM_CHANNELS;
+ }
+
+ inputBase->inputBuffer.config = inputAudio.config;
+
+ mvl2l( inputAudio.data_fx, inputBase->inputBuffer.data_fx, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels );
+
+ inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_InitConfig()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_InitConfig(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */
+)
+{
+ bool rendererConfigEnabled;
+
+ rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL );
+
+ IF( rendererConfigEnabled )
+ {
+ hIvasRend->rendererConfigEnabled = 1;
+ }
+ ELSE
+ {
+ hIvasRend->rendererConfigEnabled = 0;
+ }
+
+ IF( rendererConfigEnabled )
+ {
+ hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k;
+ hIvasRend->splitRenderConfig.dof = 3;
+ hIvasRend->splitRenderConfig.hq_mode = 0;
+ hIvasRend->splitRenderConfig.codec_delay_ms = 0;
+ hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */
+#endif
+ hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
+ hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
+ hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_GetRenderConfig()
+ *
+ *
+ *-------------------------------------------------------------------*/
+Word16 ISAR_POST_REND_GetRenderConfig(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */
+ const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */
+)
+{
+ ISAR_SPLIT_REND_CONFIG_DATA hRCin;
+
+ IF( hIvasRend == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ hRCin = hIvasRend->splitRenderConfig;
+
+ splitRenderConfig->splitRendBitRate = SPLIT_REND_768k;
+ splitRenderConfig->dof = 3;
+ splitRenderConfig->hq_mode = 0;
+ splitRenderConfig->codec_delay_ms = 0;
+ splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */
+#endif
+ splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
+ splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
+ splitRenderConfig->rendererSelection = hRCin.rendererSelection;
+
+ return IVAS_ERR_OK;
+}
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_FeedSplitBinauralBitstream()
+ *
+ *
+ *-------------------------------------------------------------------*/
+ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_REND_InputId inputId, /* i : ID of the input */
+ ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */
+)
+{
+ ivas_error error;
+ input_base *inputBase;
+ input_split_post_rend *inputSplitPostRend;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || hBits == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
+ {
+ printf( "Goo\n" );
+ return error;
+ }
+
+ inputSplitPostRend = (input_split_post_rend *) inputBase;
+ inputSplitPostRend->hBits = hBits;
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_SetHeadRotation()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_SetHeadRotation(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
+ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */
+ const Word16 sf_idx /* i : subframe index */
+)
+{
+ IVAS_QUATERNION rotQuat;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ IF( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL )
+ {
+ /* Head rotation can be set only with binaural output */
+ return IVAS_ERR_INVALID_OUTPUT_FORMAT;
+ }
+
+ hIvasRend->headRotData.headRotEnabled = 1;
+
+ /* check for Euler angle signaling */
+ IF( EQ_32( headRot.w_fx, -12582912 ) )
+ {
+ Euler2Quat_fx( deg2rad_fx( headRot.x_fx ), deg2rad_fx( headRot.y_fx ), deg2rad_fx( headRot.z_fx ), &rotQuat );
+ }
+ ELSE
+ {
+ rotQuat = headRot;
+ }
+
+ hIvasRend->headRotData.headPositions[sf_idx] = rotQuat;
+ hIvasRend->headRotData.Pos[sf_idx] = Pos;
+ hIvasRend->headRotData.sr_pose_pred_axis = rot_axis;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_SetSplitRendBFI()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_SetSplitRendBFI(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const Word16 bfi /* i: BFI flag */
+)
+{
+ hIvasRend->splitRendBFI = bfi;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * Local functions
+ *-------------------------------------------------------------------*/
+
+static ivas_error splitBinLc3plusDecode(
+ ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin,
+ ISAR_SPLIT_REND_BITS_HANDLE bits,
+ Word32 outputBuffer[BINAURAL_CHANNELS][L_FRAME48k],
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction,
+#endif
+ const int16_t SplitRendBFI )
+{
+ ivas_error error;
+ Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ Word32 lc3plusBitstreamSize;
+#else
+ Word32 lc3plusBitrateId, lc3plusBitstreamSize;
+#endif
+
+ push_wmops( "splitBinLc3plusDecode" );
+ assert( hSplitBin->hLc3plusDec != NULL );
+
+ for ( Word16 i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
+ {
+ channel_ptrs[i] = outputBuffer[i];
+ }
+
+ if ( SplitRendBFI == 0 )
+ {
+ /* Find next byte boundary */
+ while ( bits->bits_read % 8 != 0 )
+ {
+ ++bits->bits_read;
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ /* Size is in bytes */
+ assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 );
+ lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8;
+#else
+ /* Read LC3plus bitstream size info */
+ lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 );
+ lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (Word8) lc3plusBitrateId, pose_correction, (Word16) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) );
+#endif
+
+ if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, channel_ptrs ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ pop_wmops();
+ return IVAS_ERR_OK;
+}
+
+static ivas_error renderSplitBinauralWithPostRot(
+ input_split_post_rend *splitBinInput,
+ IVAS_REND_AudioBuffer outAudio,
+ const Word16 SplitRendBFI,
+ const Word16 num_subframes )
+{
+ Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ ivas_error error;
+ Word32 Cldfb_RealBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 };
+ Word32 Cldfb_ImagBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 };
+
+ IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES];
+ int16_t sf_idx, ch_idx;
+ ISAR_SPLIT_REND_BITS_DATA bits;
+ Word32 tmpCrendBuffer_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 };
+ Word32 tmpCrendBuffer_sf_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 };
+
+ ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin;
+ Word8 isPostRendInputCldfb;
+ Word16 chnlIdx, slotIdx, smplIdx;
+ Word16 preRendFrameSize_ms;
+ Word16 outBufNumSamplesPerChannel, outBufNumColPerChannel;
+ Word16 numSamplesPerChannelCacheSize, numColPerChannelCacheSize;
+
+ Word32 *readPtr_fx, *writePtr_fx;
+ Word16 Q_cldfb_final[MAX_PARAM_SPATIAL_SUBFRAMES] = { 0 };
+ Word16 Q_out[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS] = { 0 };
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ uint32_t ivas_frame_duration_us;
+#endif
+ Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame;
+ const ISAR_POST_REND_HeadRotData *pHeadRotData;
+
+ isPostRendInputCldfb = 0;
+ push_wmops( "renderSplitBinauralWithPostRot" );
+ error = IVAS_ERR_OK;
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms )
+ {
+ return IVAS_ERR_INTERNAL_FATAL;
+ }
+#endif
+
+ pHeadRotData = splitBinInput->base.ctx.pHeadRotData;
+ hSplitBin = &splitBinInput->splitPostRendWrapper;
+ convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits );
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivas_frame_duration_us = 20000;
+ if ( splitBinInput->splitPostRendWrapper.hLc3plusDec != NULL )
+ {
+ ivas_frame_duration_us = splitBinInput->splitPostRendWrapper.hLc3plusDec->config.isar_frame_duration_us;
+ }
+#endif
+
+ iNumLCLDIterationsPerFrame = 1;
+ iNumBlocksPerFrame = CLDFB_NO_COL_MAX;
+ IF( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL )
+ {
+ iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks;
+ iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations;
+ }
+
+ outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes;
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx];
+ }
+
+ IF( !SplitRendBFI )
+ {
+ hSplitBin->first_good_frame_received = 1;
+ }
+
+ IF( EQ_16( hSplitBin->first_good_frame_received, 1 ) )
+ {
+ IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ IF( !SplitRendBFI )
+ {
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend );
+#else
+ isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData );
+#endif
+ }
+ }
+
+ /*copy pose correction after MD is parsed*/
+ hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction;
+
+ /* decode audio */
+ IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
+ {
+ IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ isPostRendInputCldfb = 1;
+ }
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel;
+#else
+ preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000;
+
+ numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 );
+#endif
+
+ outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES;
+ numColPerChannelCacheSize = sub( DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ), outBufNumColPerChannel );
+
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IF( splitBinInput->numCachedSamples == 0 )
+ {
+ IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, &Q_cldfb_final[sf_idx], SplitRendBFI ); // Q_cldfb_final
+
+ /* copy data over to 5ms buffer */
+ FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
+ {
+ FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx )
+ {
+ mvl2l( Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX );
+ mvl2l( Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+
+ /* cache the remaining 15ms */
+ splitBinInput->numCachedSamples = numColPerChannelCacheSize;
+ writePtr_fx = splitBinInput->bufferData_fx;
+ FOR( slotIdx = 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; slotIdx < DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ); ++slotIdx )
+ {
+ FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
+ {
+ FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
+ {
+ *writePtr_fx++ = Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx];
+ }
+ FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
+ {
+ *writePtr_fx++ = Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx];
+ }
+ }
+ }
+ }
+ ELSE
+ {
+ Q_out[sf_idx][0] = 0;
+ Q_out[sf_idx][1] = 0;
+ if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer_fx,
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ bits.pose_correction,
+#endif
+ SplitRendBFI ) ) != IVAS_ERR_OK ) // Q0
+ {
+ return error;
+ }
+
+ /* cache the remaining 15ms */
+ splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize;
+ mvl2l( &tmpCrendBuffer_fx[0][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx, numSamplesPerChannelCacheSize );
+ mvl2l( &tmpCrendBuffer_fx[1][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize );
+ }
+ }
+ ELSE
+ {
+ /* copy from cache */
+ IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ Word16 readOffset = sub( numColPerChannelCacheSize, splitBinInput->numCachedSamples );
+ readPtr_fx = splitBinInput->bufferData_fx;
+ Q_cldfb_final[sf_idx] = Q_cldfb_final[sf_idx - 1];
+ isPostRendInputCldfb = 1;
+
+ readPtr_fx += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS;
+ FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx )
+ {
+ FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
+ {
+ FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
+ {
+ Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++;
+ }
+ FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
+ {
+ Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++;
+ }
+ }
+ }
+
+ splitBinInput->numCachedSamples -= outBufNumColPerChannel;
+ }
+ ELSE
+ {
+ Word16 readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples;
+ mvl2l( splitBinInput->bufferData_fx + readOffset, &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
+ mvl2l( splitBinInput->bufferData_fx + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
+ Q_out[sf_idx][0] = Q_out[sf_idx - 1][0];
+ Q_out[sf_idx][1] = Q_out[sf_idx - 1][1];
+ splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel;
+ }
+ }
+ }
+ }
+ ELSE
+ {
+ copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx );
+ IF( splitBinInput->numCachedSamples == 0 )
+ {
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms;
+#else
+ preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000;
+#endif
+ numSamplesPerChannelCacheSize = (Word16) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 );
+ numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel;
+ splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize;
+ }
+ ELSE
+ {
+ splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel;
+ }
+ }
+
+ /* apply pose correction if enabled */
+ FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
+ {
+ IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb )
+ {
+ /* 0DOF with LCLD codec requires CLDFB synthesis */
+ Word16 slot_idx;
+
+ FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
+ {
+ Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
+ Word16 scaleFactor = 31, Q_cldfb;
+
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx];
+ ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx];
+
+ scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) );
+ }
+ scaleFactor = sub( scaleFactor, 3 ); // guarded bits
+
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
+ {
+ Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor );
+ }
+ Q_cldfb = scaleFactor + Q_cldfb_final[sf_idx];
+ Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) );
+ cldfbSynthesis_ivas_fx( RealBuffer_fx,
+ ImagBuffer_fx,
+ &( tmpCrendBuffer_fx[ch_idx][sf_idx * outBufNumSamplesPerChannel] ),
+ hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES,
+ hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1
+ Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) );
+ Q_out[sf_idx][ch_idx] = sub( Q_cldfb, 1 );
+ }
+ }
+ ELSE IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ mvl2l( &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[0], outBufNumSamplesPerChannel );
+ mvl2l( &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[1], outBufNumSamplesPerChannel );
+
+ isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx], Q_cldfb_final[sf_idx], tmpCrendBuffer_sf_fx, Q_out[sf_idx], isPostRendInputCldfb ); // Q_out[2]
+
+ mvl2l( tmpCrendBuffer_sf_fx[0], &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
+ mvl2l( tmpCrendBuffer_sf_fx[1], &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
+ }
+ }
+ }
+ ELSE
+ {
+ IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
+ {
+ FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
+ {
+ set_l( tmpCrendBuffer_fx[ch_idx], 0, outAudio.config.numSamplesPerChannel );
+ }
+ }
+ ELSE
+ {
+ copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx );
+ }
+ }
+
+ convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits );
+
+ Word16 Q_max = 0, Q_temp;
+ FOR( Word16 i = 0; i < num_subframes; i++ )
+ {
+ maximum_s( Q_out[i], BINAURAL_CHANNELS, &Q_temp );
+ Q_max = s_max( Q_max, Q_temp );
+ }
+ Q_max = s_min( Q_max, Q13 );
+ accumulate2dArrayToBuffer_fx( tmpCrendBuffer_fx, Q_out, Q_max, &outAudio, num_subframes, outBufNumSamplesPerChannel );
+ *outAudio.q_data_fx = Q_max;
+
+ pop_wmops();
+ return error;
+}
+
+static ivas_error renderInputSplitBin(
+ input_split_post_rend *splitBinInput,
+ const AUDIO_CONFIG outConfig,
+ IVAS_REND_AudioBuffer outAudio,
+ const Word16 SplitRendBFI,
+ const Word16 num_subframes )
+{
+ ivas_error error;
+ IVAS_REND_AudioBuffer inAudio;
+
+ inAudio = splitBinInput->base.inputBuffer;
+
+ splitBinInput->base.numNewSamplesPerChannel = 0;
+
+ /* Apply input gain to new audio */
+ v_multc_fixed( inAudio.data_fx,
+ splitBinInput->base.gain_fx,
+ inAudio.data_fx,
+ inAudio.config.numSamplesPerChannel * inAudio.config.numChannels );
+
+ SWITCH( outConfig )
+ {
+ case IVAS_AUDIO_CONFIG_BINAURAL:
+ error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes );
+ BREAK;
+ default:
+ return IVAS_ERR_INVALID_OUTPUT_FORMAT;
+ }
+
+ return error;
+}
+
+static ivas_error renderActiveInputsSplitBin(
+ ISAR_POST_REND_HANDLE hIvasRend,
+ IVAS_REND_AudioBuffer outAudio )
+{
+ int16_t i;
+ input_split_post_rend *pCurrentInput;
+ ivas_error error;
+ pCurrentInput = hIvasRend->inputsSplitPost;
+ FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
+ {
+ IF( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
+ {
+ /* Skip inactive inputs */
+ ++pCurrentInput;
+ continue;
+ }
+
+ IF( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ ++pCurrentInput;
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_getSamples()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_getSamples(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */
+)
+{
+ ivas_error error;
+ Word16 numOutChannels;
+ Word16 cldfb2tdSampleFact;
+
+ /* Validate function arguments */
+ IF( hIvasRend == NULL || outAudio.data_fx == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1;
+
+ IF( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) ||
+ ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) )
+ {
+ return IVAS_ERR_INVALID_BUFFER_SIZE;
+ }
+
+ IF( LT_16( outAudio.config.numChannels, 0 ) || LT_16( MAX_OUTPUT_CHANNELS, outAudio.config.numChannels ) )
+ {
+ return IVAS_ERR_WRONG_NUM_CHANNELS;
+ }
+
+ IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL &&
+ ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" );
+ }
+
+ IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ return IVAS_ERR_WRONG_NUM_CHANNELS;
+ }
+
+ /* Clear original output buffer */
+ set_l( outAudio.data_fx, 0, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel );
+
+ IF( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+#ifndef DISABLE_LIMITER
+#ifdef DEBUGGING
+ hIvasRend->numClipping +=
+#endif
+ Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.q_data_fx );
+ limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.q_data_fx );
+#endif
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_GetSplitBinauralSamples()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+ivas_error ISAR_POST_REND_GetSplitBinauralSamples(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
+ bool *needNewFrame )
+{
+ ivas_error error;
+
+ IF( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_Close()
+ *
+ *
+ *-------------------------------------------------------------------*/
+void ISAR_POST_REND_Close(
+ ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */
+)
+{
+ UWord16 i;
+ ISAR_POST_REND_HANDLE hIvasRend;
+
+ /* Validate function arguments */
+ IF( phIvasRend == NULL || *phIvasRend == NULL )
+ {
+ return;
+ }
+ hIvasRend = *phIvasRend;
+
+ FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
+ {
+ clearInputSplitRend( &hIvasRend->inputsSplitPost[i] );
+ }
+
+ ivas_limiter_close_splitRend( &hIvasRend->hLimiter );
+
+ free( hIvasRend );
+ *phIvasRend = NULL;
+
+ return;
+}
+
+
+ivas_error ISAR_REND_SetSplitRendBitstreamHeader(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
+ const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */
+ const int16_t codec_frame_size_ms /* i: codec frame size setting */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */
+ const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */
+#endif
+)
+{
+ IF( hIvasRend == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+ hIvasRend->splitRenderConfig.codec = codec;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms;
+#endif
+ hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms;
+ hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres;
+#endif
+ return IVAS_ERR_OK;
+}
+
+#ifdef DEBUGGING
+/*-------------------------------------------------------------------*
+ * ISAR_POST_REND_GetNoCLipping()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+int32_t ISAR_POST_REND_GetNoCLipping(
+ ISAR_POST_REND_HANDLE hIvasRend )
+{
+ return hIvasRend->numClipping;
+}
+
+int32_t ISAR_POST_REND_GetCntFramesLimited(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend )
+{
+ if ( hIvasRend->hLimiter == NULL )
+ {
+ return 0;
+ }
+
+ return hIvasRend->hLimiter->cnt_frames_limited;
+}
+#endif
+
+
+#endif
diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc32086fa4c22eaf9f1790f987a71873877c6ab9
--- /dev/null
+++ b/lib_isar/lib_isar_post_rend.h
@@ -0,0 +1,225 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef LIB_ISAR_POST_REND_H
+#define LIB_ISAR_POST_REND_H
+
+#include "common_api_types.h"
+#include
+
+#ifndef SPLIT_REND_WITH_HEAD_ROT
+
+int32_t ISAR_POST_REND_void_func( void );
+
+#else
+
+/*---------------------------------------------------------------------*
+ * Renderer constants
+ *---------------------------------------------------------------------*/
+
+#define RENDERER_MAX_ISAR_MD_INPUTS 1
+#define RENDERER_MAX_BIN_INPUTS 1
+
+/*---------------------------------------------------------------------*
+ * Renderer structures
+ *---------------------------------------------------------------------*/
+
+typedef struct
+{
+ int32_t bufLenInBytes;
+ int32_t bitsWritten;
+ int32_t bitsRead;
+ ISAR_SPLIT_REND_CODEC codec;
+ ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection;
+ int16_t codec_frame_size_ms;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int16_t isar_frame_size_ms;
+ int16_t lc3plusHighRes;
+#endif
+} ISAR_POST_REND_BitstreamBufferConfig;
+
+typedef struct
+{
+ ISAR_POST_REND_BitstreamBufferConfig config;
+ uint8_t *bits;
+} ISAR_POST_REND_BitstreamBuffer;
+
+typedef enum
+{
+ ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0,
+ ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN,
+} ISAR_POST_REND_AudioConfigType;
+
+typedef struct
+{
+ IVAS_REND_AudioBufferConfig config;
+ const Word32 *data_fx;
+} ISAR_POST_REND_ReadOnlyAudioBuffer;
+
+typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE;
+typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE;
+
+typedef uint16_t ISAR_POST_REND_InputId;
+
+typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL
+{
+ ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1,
+ ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2,
+ ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3
+} ISAR_POST_REND_COMPLEXITY_LEVEL;
+
+
+/* clang-format off */
+/*----------------------------------------------------------------------------------*
+ * Renderer function prototypes
+ *----------------------------------------------------------------------------------*/
+
+/* Functions to be called before rendering */
+ivas_error ISAR_POST_REND_open(
+ ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */
+ const Word32 outputSampleRate, /* i : output sampling rate */
+ const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */
+ const bool asHrtfBinary, /* i : load hrtf binary file */
+ const Word16 nonDiegeticPan, /* i : non-diegetic object flag */
+ const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */
+ const Word16 num_subframes /* i : number of subframes */
+);
+
+/* Functions to be called before/during rendering */
+ivas_error ISAR_POST_REND_NumOutChannels(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
+ Word16 *numOutChannels /* o : number of output channels */
+);
+
+ivas_error ISAR_POST_REND_AddInput(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */
+ ISAR_POST_REND_InputId *inputId /* o : ID of the new input */
+);
+
+ivas_error ISAR_POST_REND_SetInputGain(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ const Word32 gain /* i : linear gain (not in dB) */
+);
+
+ivas_error ISAR_POST_REND_GetInputNumChannels(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ Word16 *numChannels /* o : number of channels of the input */
+);
+ivas_error ISAR_POST_REND_GetDelay(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */
+ Word16 *nSamples, /* o : Renderer delay in samples */
+ Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */
+);
+
+/* Functions to be called during rendering */
+
+ivas_error ISAR_POST_REND_FeedInputAudio(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */
+);
+
+ivas_error ISAR_POST_REND_InitConfig(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */
+);
+Word16 ISAR_POST_REND_GetRenderConfig(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */
+ const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */
+);
+ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
+ ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */
+);
+
+ivas_error ISAR_POST_REND_GetSplitBinauralSamples(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
+ bool* needNewFrame
+);
+
+ivas_error ISAR_POST_REND_SetHeadRotation(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
+ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */
+ const Word16 sf_idx /* i : subframe index */
+);
+
+ivas_error ISAR_POST_REND_SetSplitRendBFI(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ const Word16 bfi /* i: BFI flag */
+);
+
+ivas_error ISAR_POST_REND_getSamples(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
+ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */
+);
+
+/* Functions to be called after rendering */
+
+void ISAR_POST_REND_Close(
+ ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */
+);
+
+ivas_error ISAR_REND_SetSplitRendBitstreamHeader(
+ ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
+ const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */
+ const int16_t codec_frame_size_ms /* i: codec frame size setting */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ,
+ const int16_t isar_frame_size_ms, /* i: isar frame size setting */
+ const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */
+#endif
+);
+
+
+#ifdef DEBUGGING
+int32_t ISAR_POST_REND_GetNoCLipping(
+ ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */
+);
+
+int32_t ISAR_POST_REND_GetCntFramesLimited(
+ ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */
+);
+#endif
+
+#endif /* SPLIT_REND_WITH_HEAD_ROT */
+
+/* clang-format on */
+
+#endif /* LIB_ISAR_POST_REND_H */
diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c
new file mode 100644
index 0000000000000000000000000000000000000000..2149d22250b49ac533cdac18da692978d2b971e8
--- /dev/null
+++ b/lib_isar/lib_isar_pre_rend.c
@@ -0,0 +1,626 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+
+#include
+#include "options.h"
+#include
+#include "ivas_prot.h"
+#include "prot.h"
+#include "isar_cnst.h"
+#include "isar_rom_post_rend.h"
+#include "lib_isar_pre_rend.h"
+#include "isar_prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+
+
+#ifndef SPLIT_REND_WITH_HEAD_ROT
+int32_t ISAR_PRE_REND_void_func( void )
+{
+ return 0;
+}
+
+#else
+
+/*-------------------------------------------------------------------*
+ * Local constants
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Local types
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Local function prototypes
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------*
+ * Local functions
+ *-------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_PRE_REND_open()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+ivas_error ISAR_PRE_REND_open(
+ SPLIT_REND_WRAPPER *hSplitRendWrapper,
+ ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
+ const Word32 OutSampleRate,
+ const Word16 cldfb_in_flag,
+ const Word16 pcm_out_flag,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */
+#else
+ const int16_t num_subframes, /* i: number of subframes */
+#endif
+ const int16_t mixed_td_cldfb_flag )
+{
+ ivas_error error, ch, num_ch;
+ UWord8 isCldfbNeeded = 0;
+ Word16 cldfb_in_flag_local = cldfb_in_flag;
+
+ if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ),
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ &pSplitRendConfig->isar_frame_size_ms,
+#endif
+ &pSplitRendConfig->codec_frame_size_ms,
+ cldfb_in_flag_local,
+ pcm_out_flag, (int16_t)
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivas_frame_size
+#else
+ num_subframes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( mixed_td_cldfb_flag )
+ {
+ cldfb_in_flag_local = 0;
+ }
+
+ IF( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ IF( EQ_16( cldfb_in_flag_local, 0 ) )
+ {
+ isCldfbNeeded = 1;
+ }
+ ELSE IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag_local )
+ {
+ isCldfbNeeded = 1;
+ }
+ ELSE IF( pcm_out_flag && cldfb_in_flag_local )
+ {
+ isCldfbNeeded = 1;
+ }
+
+ hSplitRendWrapper->hCldfbHandles = NULL;
+
+ IF( isCldfbNeeded )
+ {
+ IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) );
+ }
+ num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL;
+ }
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL;
+ }
+
+ num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS;
+
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ),
+ CLDFB_ANALYSIS,
+ OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ IF( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+
+ IF( EQ_16( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
+ {
+ if ( ( error = isar_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ ,
+ OutSampleRate
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ IF( EQ_16( pcm_out_flag, 0 ) )
+ {
+ IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) )
+ {
+ if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ ivas_frame_size
+#else
+ num_subframes
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ Word16 iNumBlocksPerFrame;
+ iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20;
+
+ IF( ( error = isar_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_PRE_REND_close()
+ *
+ *
+ *------------------------------------------------------------------------*/
+void ISAR_PRE_REND_close(
+ SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
+ IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */
+)
+{
+ Word16 i;
+
+ IF( hSplitBinRend->hBinHrSplitPreRend != NULL )
+ {
+ isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend );
+ }
+
+ IF( hSplitBinRend->hSplitBinLCLDEnc != NULL )
+ {
+ isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc );
+ }
+
+ IF( hSplitBinRend->hCldfbHandles != NULL )
+ {
+ Word16 num_ch, ch;
+ num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
+ FOR( ch = 0; ch < num_ch; ch++ )
+ {
+ IF( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL )
+ {
+ deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] );
+ hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL;
+ }
+ }
+
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ IF( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL )
+ {
+ deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] );
+ hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL;
+ }
+ }
+#endif
+
+ free( hSplitBinRend->hCldfbHandles );
+ hSplitBinRend->hCldfbHandles = NULL;
+ }
+
+ IF( hSplitBinRend->hLc3plusEnc != NULL )
+ {
+ ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc );
+ }
+
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
+ {
+ IF( hSplitBinRend->lc3plusDelayBuffers[i] != NULL )
+ {
+ free( hSplitBinRend->lc3plusDelayBuffers[i] );
+ hSplitBinRend->lc3plusDelayBuffers[i] = NULL;
+ }
+ if ( hSplitBinRend->lc3plusDelayBuffers_fx[i] != NULL )
+ {
+ free( hSplitBinRend->lc3plusDelayBuffers_fx[i] );
+ hSplitBinRend->lc3plusDelayBuffers_fx[i] = NULL;
+ }
+ }
+
+ IF( pSplitRendEncBuffer != NULL )
+ {
+
+ IF( pSplitRendEncBuffer->data != NULL )
+ {
+ free( pSplitRendEncBuffer->data );
+ pSplitRendEncBuffer->data = NULL;
+ }
+
+ pSplitRendEncBuffer->config.numChannels = 0;
+ pSplitRendEncBuffer->config.numSamplesPerChannel = 0;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------*
+ * ISAR_PRE_REND_GetMultiBinPoseData()
+ *
+ *
+ *-------------------------------------------------------------------------*/
+
+void ISAR_PRE_REND_GetMultiBinPoseData(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */
+)
+{
+ isar_renderSplitGetMultiBinPoseData_fx( pSplit_rend_config, pMultiBinPoseData, rot_axis );
+}
+
+/*-------------------------------------------------------------------------
+ * Function ISAR_PRE_REND_MultiBinToSplitBinaural()
+ *
+ *
+ *------------------------------------------------------------------------*/
+ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
+ SPLIT_REND_WRAPPER *hSplitBin,
+ const IVAS_QUATERNION headPosition,
+ const Word32 SplitRendBitRate,
+ ISAR_SPLIT_REND_CODEC splitCodec,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const Word16 isar_frame_size_ms, /* i: ISAR framesize */
+#endif
+ Word16 codec_frame_size_ms,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits,
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ const Word16 max_bands,
+ float *output[],
+ Word32 *pOutput_fx[],
+ const Word16 low_res_pre_rend_rot,
+ const Word16 cldfb_in_flag,
+ const Word16 pcm_out_flag,
+ const Word16 ro_md_flag,
+ Word16 Q_buff,
+ Word16 *Q_out )
+{
+ ivas_error error;
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ int32_t bit_len, target_md_bits, available_bits, tmp_32;
+#else
+ Word32 bit_len, target_md_bits, actual_md_bits, available_bits, tmp_32;
+#endif
+ Word16 q1 = 31, q2 = 31, q_final, Q_cldfb, tmp, tmp_e;
+ Word16 i, j;
+ error = IVAS_ERR_OK;
+ Word16 Q_buff_re, Q_buff_im;
+ push_wmops( "ISAR_PRE_REND_MultiBinToSplitBinaural" );
+#ifdef CLDFB_SYNTH_DEBUG
+ /* FILE *fp = fopen( "Fixed_code_output.txt", "ab+" );
+ FILE *fp1 = fopen( "Fixed_code_cldfb_state.txt", "ab+" );
+ FILE *fp = fopen( "Float_code_output.txt", "ab+" );
+ FILE *fp1 = fopen( "Float_code_cldfb_state.txt", "ab+" );*/
+#endif
+ output;
+ Q_buff_re = Q_buff;
+ move16();
+ Q_buff_im = Q_buff;
+ move16();
+ IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ set_fix_rotation_mat_fx( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat_fx, &hSplitBin->multiBinPoseData );
+ set_pose_types_fx( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData );
+ }
+
+ IF( EQ_16( cldfb_in_flag, 0 ) )
+ {
+ error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate,
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ isar_frame_size_ms,
+#endif
+ codec_frame_size_ms, pBits, max_bands, pOutput_fx, Q_out[0], low_res_pre_rend_rot, pcm_out_flag, ro_md_flag );
+
+ pop_wmops();
+ return error;
+ }
+
+ IF( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ /* Time-align pose correction to delay of LC3plus */
+ lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, &Q_buff );
+ Q_buff_re = Q_buff;
+ move16();
+ Q_buff_im = Q_buff;
+ move16();
+ }
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ actual_md_bits = pBits->bits_written;
+#endif
+ IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
+ {
+ target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
+
+#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ actual_md_bits = pBits->bits_written;
+#endif
+ /*float2fix, to be removed*/
+ Word16 Q_Cldfb_re = 31, Q_Cldfb_im = 31;
+ move16();
+ move16();
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Q_Cldfb_re = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_re );
+ Q_Cldfb_im = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_im );
+ }
+ }
+ FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_re );
+ Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_im );
+ }
+ }
+ Q_buff_re = add( Q_Cldfb_re, Q_buff );
+ Q_buff_im = add( Q_Cldfb_im, Q_buff );
+ Word16 exp_cldfb_re = sub( 31, Q_buff_re );
+ Word16 exp_cldfb_im = sub( 31, Q_buff_im );
+ isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
+ }
+
+ IF( EQ_16( pcm_out_flag, 0 ) )
+ {
+ pBits->codec = splitCodec;
+ pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
+
+ IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
+ available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
+ available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ available_bits = L_sub( available_bits, pBits->bits_written );
+#else
+ actual_md_bits = L_sub( pBits->bits_written, actual_md_bits );
+ available_bits = L_sub( available_bits, actual_md_bits );
+#endif
+ pBits->codec_frame_size_ms = codec_frame_size_ms;
+ q_final = sub( s_min( Q_buff_re, Q_buff_im ), 2 );
+ FOR( i = 0; i < hSplitBin->hSplitBinLCLDEnc->iChannels; i++ )
+ {
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
+ Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
+ }
+ }
+ isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final );
+ Q_buff_re = q_final;
+ move16();
+ Q_buff_im = q_final;
+ move16();
+ }
+ ELSE
+ {
+ Word16 ch, slot_idx, num_slots, ivas_fs;
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
+ ivas_fs = shr( tmp, sub( 15, tmp_e ) ); // Q0
+ // ivas_fs = (Word16) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
+
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( L_mult0( CLDFB_NO_COL_MAX, ivas_fs ), 20, &tmp_e );
+ num_slots = shr( tmp, sub( 15, tmp_e ) ); // Q0
+ // num_slots = (Word16) CLDFB_NO_COL_MAX * ivas_fs / 20;
+ /* CLDFB synthesis of main pose */
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX];
+ Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX];
+ q1 = 31;
+ q2 = 31;
+ move16();
+ move16();
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 );
+ q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 );
+ }
+ q_final = s_min( q1, q2 );
+ q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) );
+ q_final = sub( q_final, 3 ); // guard bits
+ q_final = s_min( q_final, Q25 );
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
+ Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
+ }
+
+ FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
+ {
+ Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx];
+ move32();
+ Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx];
+ move32();
+ }
+
+ Q_cldfb = q_final;
+ move16();
+ Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split ) );
+ cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1
+ Q_out[ch] = sub( Q_cldfb, 1 );
+ move16();
+ hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split = Q_out[ch];
+ move16();
+ fixedToFloat_arrL( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length );
+ }
+
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
+ IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, pOutput_fx, Q_out[0] ) ) != IVAS_ERR_OK )
+#else
+ IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, pOutput_fx ) ) != IVAS_ERR_OK )
+#endif
+ {
+ return error;
+ }
+ }
+ }
+ ELSE
+ {
+ Word16 ch, slot_idx;
+ /* CLDFB synthesis of main pose */
+ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
+ {
+ Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX];
+ Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX];
+ q1 = 31;
+ move16();
+ q2 = 31;
+ move16();
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 );
+ q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 );
+ }
+ q_final = s_min( q1, q2 );
+ q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) );
+ q_final = sub( q_final, 3 ); // guard bits
+ q_final = s_min( q_final, Q25 );
+ FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ )
+ {
+ Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) );
+ Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) );
+ }
+
+ FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
+ {
+ Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx];
+ move32();
+ Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx];
+ move32();
+ }
+
+ Q_cldfb = q_final;
+ move16();
+ Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split ) );
+ cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1
+ Q_out[ch] = sub( Q_cldfb, 1 );
+ move16();
+ hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_split = Q_out[ch];
+ move16();
+ }
+
+ pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
+ pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
+ }
+
+ /*zero pad*/
+ IF( pcm_out_flag )
+ {
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e );
+ bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
+ // bit_len = SplitRendBitRate / FRAMES_PER_SEC;
+ }
+ ELSE
+ {
+ IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
+ {
+ // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
+
+ bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) );
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e );
+ bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+ }
+ ELSE
+ {
+ tmp_e = 0;
+ tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e );
+ bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0
+ // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
+ // bit_len = SplitRendBitRate * bit_len / 1000;
+ tmp_e = 0;
+ tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e );
+ bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0
+ }
+ }
+
+ WHILE( LT_32( pBits->bits_written, bit_len ) )
+ {
+ ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
+ }
+
+ pop_wmops();
+ /* fclose(fp);
+ fclose(fp1);*/
+ return error;
+}
+
+#endif
diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe64e4911a17346502f8978667c24f4abe1f6732
--- /dev/null
+++ b/lib_isar/lib_isar_pre_rend.h
@@ -0,0 +1,92 @@
+/******************************************************************************************************
+
+ (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#ifndef LIB_ISAR_PRE_REND_H
+#define LIB_ISAR_PRE_REND_H
+
+#include "isar_stat.h"
+#include "isar_prot.h"
+
+#ifndef SPLIT_REND_WITH_HEAD_ROT
+
+int32_t ISAR_PRE_REND_void_func( void );
+
+#else
+ivas_error ISAR_PRE_REND_open(
+ SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
+ ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */
+ const int32_t output_Fs, /* i: output sampling rate */
+ const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
+ const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */
+#else
+ const int16_t num_subframes, /* i: number of subframes */
+#endif
+ const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */
+);
+
+void ISAR_PRE_REND_close(
+ SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
+ IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */
+);
+
+void ISAR_PRE_REND_GetMultiBinPoseData(
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */
+);
+
+ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
+ const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
+ const Word32 SplitRendBitRate, /* i: Split renderer bitrate */
+ ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
+#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
+ const Word16 isar_frame_size_ms, /* i: ISAR framesize */
+#endif
+ Word16 codec_frame_size_ms, /* i/o: Split renderer codec framesize */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: Split renderer bitstream handle */
+ Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */
+ Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */
+ const Word16 max_bands, /* i: CLDFB bands */
+ float *output[], /* i/o: PCM in/out buffer */
+ Word32 *pOutput_fx[], /* i: low time resolution pre-renderer flag */
+ const Word16 low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
+ const Word16 cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
+ const Word16 pcm_out_flag, /* i: Flag to indicate PCM output */
+ const Word16 ro_md_flag, /* i: Flag to indicate real only metadata for yaw */
+ Word16 Q_buff,
+ Word16 *Q_out );
+
+#endif
+#endif /* LIB_ISAR_PRE_REND_H */
diff --git a/lib_lc3plus/.clang-format b/lib_lc3plus/.clang-format
new file mode 100644
index 0000000000000000000000000000000000000000..47a38a93f2dbdd6d944f9dddc3465e3fb65aec29
--- /dev/null
+++ b/lib_lc3plus/.clang-format
@@ -0,0 +1,2 @@
+DisableFormat: true
+SortIncludes: Never
diff --git a/lib_lc3plus/adjust_global_gain_fx.c b/lib_lc3plus/adjust_global_gain_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6067b59122b40b106640b462b10d4af167ca80f
--- /dev/null
+++ b/lib_lc3plus/adjust_global_gain_fx.c
@@ -0,0 +1,186 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+
+
+void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off,
+#ifdef ENABLE_HR_MODE
+ Word32 *gain,
+#else
+ Word16 *gain,
+#endif
+ Word16 *gain_e,
+ Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode, Word16 frame_dms
+#endif
+ )
+{
+
+ Word32 L_tmp;
+ Word16 delta, delta2;
+#ifdef ENABLE_HR_MODE
+ Word16 gg_idx_inc;
+ Word16 gg_idx_inc_max;
+ Word16 gg_idx_inc_s;
+# ifdef CR8_G_ADD_75MS
+ Word32 factor;
+# else
+ Word16 factor;
+# endif
+#endif
+
+#ifdef DYNMEM_COUNT
+#if defined(ENABLE_HR_MODE)
+ Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct {
+ Word32 L_tmp;
+ Word16 delta, delta2;
+ Word16 gg_idx_inc;
+ Word16 gg_idx_inc_max;
+ Word16 gg_idx_inc_s;
+ Word16 factor;
+ }));
+#else
+ Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct {
+ Word32 L_tmp;
+ Word16 delta, delta2;
+ }));
+#endif /* ENABLE_HR_MODE */
+#endif /* DYNMEM_COUNT */
+
+#ifdef ENABLE_HR_MODE
+ IF (sub(frame_dms, 25) == 0)
+ {
+ IF (sub(target, 520) < 0)
+ {
+ factor = 3; move16();
+ gg_idx_inc_max = 30; move16();
+ } ELSE {
+ factor = 4; move16();
+ gg_idx_inc_max = 40; move16();
+ }
+ }
+ ELSE IF (sub(frame_dms, 50) == 0)
+ {
+ factor = 2; move16();
+ gg_idx_inc_max = 20; move16();
+ }
+#ifdef CR8_G_ADD_75MS
+ ELSE IF (sub(frame_dms, 75) == 0)
+ {
+ factor = 40265318; move16(); // factor = 1.2 * 2^25
+ gg_idx_inc_max = 12 ; move16();
+ }
+#endif
+ ELSE
+ {
+ factor = 1; move16();
+ gg_idx_inc_max = 10; move16();
+ }
+#endif
+
+ IF (sub(nBits, adjust_global_gain_tables[0][fs_idx]) < 0)
+ {
+ delta = mult_r(add(nBits, 48), 2048);
+ }
+ ELSE IF (sub(nBits, adjust_global_gain_tables[1][fs_idx]) < 0)
+ {
+ delta = mult_r(add(nBits, adjust_global_gain_tables[4][fs_idx]), adjust_global_gain_tables[3][fs_idx]);
+ }
+ ELSE IF (sub(nBits, adjust_global_gain_tables[2][fs_idx]) < 0)
+ {
+ delta = mult_r(nBits, 683);
+ }
+ ELSE
+ {
+ delta = mult_r(adjust_global_gain_tables[2][fs_idx], 683);
+ }
+ delta2 = add(delta, 2);
+
+ *gainChange = 0; move16();
+
+ test();
+ IF (sub(*gg_idx, 255) == 0 && sub(nBits, target) > 0)
+ {
+ *gainChange = 1; move16();
+ }
+
+ test(); test(); test();
+ IF ((sub(*gg_idx, 255) < 0 && sub(nBits, target) > 0) || (*gg_idx > 0 && sub(nBits, sub(target, delta2)) < 0))
+ {
+#ifdef ENABLE_HR_MODE
+ IF (hrmode)
+ {
+ IF (sub(nBits, target) > 0)
+ {
+ gg_idx_inc = sub(nBits, target);
+#ifdef CR8_G_ADD_75MS
+ IF (sub(frame_dms, 75) == 0)
+ {
+ gg_idx_inc = extract_l(L_shr_pos(Mpy_32_16_lc3plus(factor, gg_idx_inc), 10)); // Mpy_32_16_lc3plus(1.2*2^25, gg_idx_inc), 25 - 15)
+ gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s);
+ gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s));
+ gg_idx_inc = add(gg_idx_inc, 1); // adding 1 instead of 1.2
+ }
+ ELSE
+#endif
+ {
+ gg_idx_inc = extract_l(L_mult0(gg_idx_inc, factor));
+ gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s);
+ gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s));
+ gg_idx_inc = add(gg_idx_inc, factor);
+ }
+ gg_idx_inc = s_min(gg_idx_inc, gg_idx_inc_max);
+
+ *gg_idx = add(*gg_idx, gg_idx_inc); move16();
+ }
+
+ *gg_idx = s_min(*gg_idx, 255); move16();
+ }
+ ELSE
+#endif
+ {
+ test();
+ IF (sub(nBits, sub(target, delta2)) < 0)
+ {
+ *gg_idx = sub(*gg_idx, 1); move16();
+ }
+ ELSE IF (sub(*gg_idx, 254) == 0 || sub(nBits, add(target, delta)) < 0)
+ {
+ *gg_idx = add(*gg_idx, 1); move16();
+ }
+ ELSE
+ {
+ *gg_idx = add(*gg_idx, 2); move16();
+ }
+ }
+
+ *gg_idx = s_max(*gg_idx, sub(gg_idx_min, gg_idx_off)); move16();
+
+#ifdef ENABLE_HR_MODE
+ L_tmp = Mpy_32_16_lc3plus(0x3CBE6B83, L_shl_pos(add(*gg_idx, gg_idx_off), 7));
+#else
+ L_tmp = L_shl_pos(L_mult0(add(*gg_idx, gg_idx_off), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
+#endif
+ *gain_e = add(extract_l(L_shr_pos(L_tmp, 25)), 1); /* get exponent */
+#ifdef ENABLE_HR_MODE
+ *gain = BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000));
+#else
+ *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000)));
+#endif
+ *gainChange = 1; move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/al_fec.c b/lib_lc3plus/al_fec.c
new file mode 100644
index 0000000000000000000000000000000000000000..7579a21b0f0c4d95c4632c302e653294c8b9d332
--- /dev/null
+++ b/lib_lc3plus/al_fec.c
@@ -0,0 +1,2379 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+
+
+#include "functions.h"
+#include "rom_basop_util.h"
+#include
+#include
+#include
+#include
+
+/* channel coder specific constants and macros */
+#define RS16_CW_LEN_MAX 15
+
+#define FEC_N_MODES 4
+#define FEC_N_SYNDROMES_MAX 6
+#define FEC_N_ERR_POS_MAX 3
+#define FEC_N_ELP_COEFF_MAX 4
+#define FEC_N_ERR_SYMB_MAX 3
+#define FEC_N_MODE_DETECTION_CW 6
+
+#define SYNDROME_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_SYNDROMES_MAX)
+#define ELP_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ELP_COEFF_MAX)
+#define ERR_POS_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_POS_MAX)
+#define ERR_SYMB_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_SYMB_MAX)
+#define DEG_ELP_IDX(mode_index, cw_index) ((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index))
+
+#define FEC_TOTAL_SYNDROME_SIZE (FEC_N_SYNDROMES_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW)
+#define FEC_TOTAL_ELP_SIZE (FEC_N_ELP_COEFF_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW)
+#define FEC_TOTAL_ERR_POS_SIZE (FEC_N_ERR_POS_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW)
+#define FEC_TOTAL_ERROR_SIZE (FEC_N_ERR_SYMB_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW)
+#define FEC_TOTAL_DEG_ELP_SIZE (FEC_N_MODES * FEC_N_MODE_DETECTION_CW)
+
+#define ERROR_REPORT_BEC_MASK ((0x0FFF)>>1)
+#define ERROR_REPORT_EP1_OK ((0x1000)>>1)
+#define ERROR_REPORT_EP2_OK ((0x2000)>>1)
+#define ERROR_REPORT_EP3_OK ((0x4000)>>1)
+#define ERROR_REPORT_EP4_OK ((0x8000)>>1)
+#define ERROR_REPORT_ALL_OK (ERROR_REPORT_EP1_OK | ERROR_REPORT_EP2_OK | ERROR_REPORT_EP3_OK | ERROR_REPORT_EP4_OK)
+
+/* debugging switches */
+
+/* constants concerning mode detection */
+#define EP_RISK_THRESH_NS_M 21990
+#define EP_RISK_THRESH_NS_E -23
+#define EP_RISK_THRESH_OS_M 25166
+#define EP_RISK_THRESH_OS_E -10
+
+#define SIMPLE_FLOAT_1_MANTISSA 16384
+
+#define FEC_STATIC static
+
+/* DISCLAIMER: Strict instrumentation of GF16 arithmetic would have to take into account
+ * the initial conversion of the arguments from UWord8 to Word16 (one move16() per argument).
+ * Behind this is the assumption that one would store GF16 elements in Word16 for strict BASOP
+ * implementation.
+ */
+
+#define GF16_MUL(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), shl((b), 4))])
+#define GF16_MUL0(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), (b))])
+#define GF16_ADD(a, b) (UWord8) s_xor((a), (b))
+
+/* tables for finite field arithmetic */
+/* tables for arithmetic in GF(16) *
+ * generator polynomial: 19
+ * unit group generator (g): 2
+ */
+
+static const UWord8 gf16_g_pow[16] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1};
+/* g_pow[i] contains g^i*/
+
+static const UWord8 gf16_log_g[16] = {255, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12};
+/* log_g[n] contains contains the value i such that g^i = n for n=1, 2, ..., 15, log_g[0] is set to 255 */
+
+static const UWord8 gf16_inv_table[16] = {255, 1, 9, 14, 13, 11, 7, 6, 15, 2, 12, 5, 10, 4, 3, 8};
+/* gf16_inv_table[n] contains the multiplicative inverse of n in GF(16) (1/0 is set to 255)*/
+
+/* RS16 generating polynomials (from lowest to highest coefficient without leading 1)*/
+
+static const UWord8 rs16_gp_d3[] = {8, 6};
+static const UWord8 rs16_gp_d5[] = {7, 8, 12, 13};
+static const UWord8 rs16_gp_d7[] = {12, 10, 12, 3, 9, 7};
+
+/* FEC mode signaling polynomials */
+
+#define EP_SIG_POLY_DEG 12
+
+static const UWord8 sig_polys[4][15] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {7, 15, 5, 6, 14, 9, 1, 3, 12, 10, 13, 3, 2, 0, 0},
+ {7, 11, 14, 1, 2, 3, 12, 11, 6, 15, 7, 6, 12, 0, 0},
+ {6, 15, 12, 2, 9, 15, 2, 8, 12, 3, 10, 5, 4, 0, 0}};
+
+static const UWord8 sig_poly_syndr[4][6] = {
+ {0, 0, 0, 0, 0, 0}, {0, 4, 5, 11, 5, 8}, {0, 5, 9, 0, 1, 7}, {0, 12, 5, 12, 9, 8}};
+
+/* bit count table for error report (0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111) */
+
+static const UWord8 rs16_bit_count_table[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+/* List of RS16 generators by Hamming distance */
+
+static const UWord8 *const rs16_gp_by_hd[8] = {NULL, NULL, NULL, rs16_gp_d3, NULL, rs16_gp_d5, NULL, rs16_gp_d7};
+
+/* fec config data */
+
+static const UWord8 hamming_distance_by_mode0[] = {1, 3, 3, 5, 7};
+static const UWord8 hamming_distance_by_mode1[] = {1, 1, 3, 5, 7};
+
+static const UWord8 crc1_bytes_by_mode0[] = {0, 3, 2, 2, 2};
+static const UWord8 crc1_bytes_by_mode1[] = {0, 3, 3, 3, 3};
+static const UWord8 crc2_bytes_by_mode[] = {0, 0, 2, 2, 2};
+
+/* fec mode risk table */
+typedef struct
+{
+ UWord32 mantissa;
+ Word16 exponent;
+} simple_float;
+
+static const simple_float risk_table_f[4][4] = {{{16384, 0}, {16384, 0}, {16384, 0}, {16384, 0}},
+ {{16384, -8}, {26880, -1}, {16384, 0}, {16384, 0}},
+ {{16384, -16}, {26880, -9}, {20475, -2}, {16384, 0}},
+ {{16384, -24}, {26880, -17}, {20475, -10}, {19195, -4}}};
+/* bit error limits for slot size 40 */
+static Word16 const low_br_max_bit_errors_by_mode[] = {0, 0, 3, 9, 18};
+
+/*
+corresponding float values:
+ {1.f, 1.f, 1.f, 1.f},
+ {0.00390625f, 0.820312f, 1.f, 1.f},
+ {1.52588e-05f, 0.00320435f, 0.312424f, 1.f},
+ {5.96046e-08f, 1.2517e-05f, 0.00122041f, 0.0732243f}
+*/
+
+/* internal encoder routines */
+
+FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords);
+
+FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode,
+ Word16 signal_mode);
+
+/* internal decoder routines */
+
+FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords);
+
+FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes,
+ Word16 slot_bytes, Word16 pc_split);
+
+FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *iobuf, Word16 data_bytes, UWord8 *cw_buf,
+ Word16 slot_bytes, Word16 pc_split, int *bfi);
+
+FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report,
+ int *bfi, UWord8 *array_of_trust, int ccc_flag_flag, Word16 *n_pccw, void *scratch);
+
+FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg);
+
+FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg);
+
+FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg);
+
+FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 hamming_distance);
+
+FEC_STATIC Word16 rs16_factorize_elp(UWord8 *error_locations, UWord8 *elp, Word16 deg_elp, Word16 max_pos);
+
+FEC_STATIC void rs16_calculate_errors(UWord8 *errors, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t);
+
+/* auxiliary routines */
+
+FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check);
+
+FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp,
+ UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb);
+
+FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes);
+
+FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 epmr_position);
+
+FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size);
+
+FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check);
+
+FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2);
+
+FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2);
+
+FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split);
+
+FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes);
+
+FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index);
+
+
+
+Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 n_pccw;
+ );
+
+ IF (sub(fec_mode, 3) == 0)
+ {
+ n_pccw = round_fx(L_sub(L_mult(2636, slot_bytes), 117377));
+ }
+ ELSE IF (sub(fec_mode, 4) == 0)
+ {
+ n_pccw = round_fx(L_sub(L_mult(2178, slot_bytes), 129115));
+ }
+ ELSE
+ {
+ n_pccw = 0; move16();
+ }
+
+ if (ccc_flag == 1 || sub(slot_bytes, 80) < 0)
+ {
+ n_pccw = 0; move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return n_pccw;
+}
+
+FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 n_crc;
+ );
+
+ n_crc = crc1_bytes_by_mode1[fec_mode]; move16();
+ if (sub(slot_bytes, 40) == 0)
+ {
+ n_crc = crc1_bytes_by_mode0[fec_mode]; move16();
+ }
+
+ IF (pc_split > 0)
+ {
+ n_crc = add(n_crc, crc2_bytes_by_mode[fec_mode]);
+ }
+ Dyn_Mem_Deluxe_Out();
+ return n_crc;
+}
+
+FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 i;
+ );
+
+ slot_bytes = shl(slot_bytes, 1);
+
+ FOR (i = 0; slot_bytes > 0; i++)
+ {
+ slot_bytes = sub(slot_bytes, RS16_CW_LEN_MAX);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return i;
+}
+
+FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 i;
+ );
+
+ slot_nibbles = sub(slot_nibbles, add(codeword_index, 1));
+ slot_nibbles = sub(slot_nibbles, DEPR_i_mult(n_codewords, 13));
+
+ FOR (i = 12; slot_nibbles >= 0; i++)
+ {
+ slot_nibbles = sub(slot_nibbles, n_codewords);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return add(i, 1);
+}
+
+/* Encoder */
+
+Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes)
+/* not time critical */
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 n_codewords, payload_size;
+ );
+
+ n_codewords = get_n_codewords(slot_bytes);
+
+ assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX);
+ payload_size = slot_bytes; move16();
+
+ IF (fec_mode > 0)
+ {
+ IF (fec_mode == 1)
+ {
+ payload_size = sub(payload_size, 1);
+ }
+ ELSE
+ {
+ payload_size = sub(payload_size, DEPR_i_mult(sub(fec_mode, 1), n_codewords));
+ }
+ IF (slot_bytes == 40)
+ {
+ payload_size = sub(payload_size, crc1_bytes_by_mode0[fec_mode]); move16();
+ }
+ ELSE
+ {
+ payload_size = sub(payload_size, crc1_bytes_by_mode1[fec_mode]); move16();
+ }
+
+ IF (ccc_flag == 0 && fec_mode > 2 && slot_bytes >= 80)
+ {
+ payload_size = sub(payload_size, crc2_bytes_by_mode[fec_mode]);
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return payload_size;
+}
+
+Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes)
+/* not time critical */
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 n_codewords, pc_split, tmp;
+ int i;
+ );
+
+ n_codewords = get_n_codewords(slot_bytes);
+
+ assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX);
+ pc_split = DEPR_i_mult(DEPR_i_mult(n_pccw, -2), sub(fec_mode, 1));
+
+ IF (fec_mode == 1 || slot_bytes < 80)
+ {
+ pc_split = 0; move16();
+ }
+ ELSE
+ {
+ FOR (i = 0; i < n_pccw; i++)
+ {
+ tmp = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), sub(n_codewords, i + 1));
+ assert(tmp == (2 * slot_bytes + i) / n_codewords);
+ pc_split = add(pc_split, tmp);
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return pc_split;
+}
+
+/* functions for EPMR handling */
+FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes)
+/* swap epmr bits with bits that will be positioned at 30 and 32 in code word 0 */
+{
+ Dyn_Mem_Deluxe_In(
+ UWord8 tmp;
+ int ind0, ind1, position;
+ );
+
+ position = sub(get_codeword_length(get_n_codewords(slot_bytes), shl(slot_bytes, 1), 0), 1);
+
+ IF (sub(slot_bytes, 40) == 0)
+ {
+ ind0 = sub(shl(crc1_bytes_by_mode0[mode], 1), 1);
+ }
+ ELSE
+ {
+ ind0 = sub(shl(crc1_bytes_by_mode1[mode], 1), 1);
+ }
+
+ ind1 = sub(position, sub(hamming_distance_by_mode0[mode], 1));
+
+ /* swap bits 2 and 3 of dw0[ind0] with bits 0 and 1 of dw0[ind1] */
+ tmp = (UWord8) s_and(shr(dw0[ind0],2), 3);
+ dw0[ind0] = (UWord8) s_and(dw0[ind0], 3);
+ dw0[ind0] = (UWord8) s_or(dw0[ind0], shl(s_and(dw0[ind1], 3),2));
+ dw0[ind1] = (UWord8) s_and(dw0[ind1], 12);
+ dw0[ind1] = (UWord8) s_or(dw0[ind1], tmp);
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 position)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 epmr;
+ );
+ epmr = s_and(cw0[position], 3);
+
+ Dyn_Mem_Deluxe_Out();
+ return epmr;
+}
+
+FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size)
+{
+ Dyn_Mem_Deluxe_In(
+ int ncrc1;
+ Word16 epmr;
+ );
+
+ ncrc1 = crc1_bytes_by_mode1[mode];
+
+ if (sub(slot_size, 40) == 0)
+ {
+ ncrc1 = crc1_bytes_by_mode0[mode];
+ }
+
+ epmr = shr(dw0[2 * ncrc1 - 1], 2);
+
+ Dyn_Mem_Deluxe_Out();
+ return epmr;
+}
+
+
+FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes,
+ Word16 slot_bytes, Word16 pc_split)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 data_offset, n_crc1, n_crc2, tmp;
+ int i, j;
+ );
+
+ tmp = sub(slot_bytes, data_bytes);
+ data_offset = add(tmp, tmp);
+
+ /* extract and reverse data*/
+ j = sub(add(slot_bytes, slot_bytes), 1);
+ FOR (i = 0; i < data_bytes; i++)
+ {
+ cw_buf[j--] = (UWord8)s_and(iobuf[i], 15); move16();
+ cw_buf[j--] = (UWord8)shr(iobuf[i], 4); move16();
+ }
+
+ /* add crc hashes */
+ IF (sub(slot_bytes, 40) == 0)
+ {
+ n_crc1 = crc1_bytes_by_mode0[mode]; move16();
+ }
+ ELSE
+ {
+ n_crc1 = crc1_bytes_by_mode1[mode]; move16();
+ }
+
+ IF (pc_split > 0 && sub(mode, 1) > 0)
+ {
+ n_crc2 = crc2_bytes_by_mode[mode]; move16();
+ }
+ ELSE
+ {
+ n_crc2 = 0; move16();
+ }
+
+ IF (n_crc2)
+ {
+ crc2(cw_buf + data_offset + 2 * data_bytes - pc_split, pc_split, cw_buf + data_offset - 2 * n_crc2, n_crc2, 0);
+ }
+ IF (n_crc1)
+ {
+ crc1(cw_buf + data_offset, 2 * data_bytes - pc_split, epmr, cw_buf + data_offset - 2 * (n_crc1 + n_crc2), n_crc1,
+ 0);
+ }
+
+ tmp = add(n_crc1, n_crc2);
+ data_offset = sub(data_offset, add(tmp, tmp));
+
+ dw0_bitswap(cw_buf + data_offset, mode, slot_bytes);
+
+ Dyn_Mem_Deluxe_Out();
+ return data_offset;
+}
+
+void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw,
+ void *scratch)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 n_codewords, codeword_length, hd, redundancy_nibbles, cw_offset, dw_offset, pc_split;
+ int i, j;
+ UWord8 *cw_buf;
+ );
+
+ cw_offset = 0; move16();
+ dw_offset = 0; move16();
+ pc_split = 0; move16();
+ cw_buf = scratch;
+
+ n_codewords = get_n_codewords(slot_bytes);
+ assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX);
+
+ /* some sanity checks */
+ {
+ int tmp = slot_bytes;
+ assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) &&
+ "fec_encoder: slot_bytes out of range");
+ tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy
+ tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1
+ tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2
+ assert(data_bytes == tmp && "fec_encoder: inconsistent payload size");
+ assert(n_codewords - n_pccw >= 6);
+ }
+
+ /* data preproc: re-ordering and hash extension */
+ pc_split = fec_get_n_pc(mode, n_pccw, slot_bytes);
+
+ dw_offset = fec_data_preproc(mode, epmr, iobuf, cw_buf, data_bytes, slot_bytes, pc_split);
+
+ /* encoding of first data word*/
+ hd = hamming_distance_by_mode0[mode]; move16();
+ redundancy_nibbles = sub(hd, 1);
+ codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0);
+
+ assert(codeword_length == (2 * slot_bytes - 1) / n_codewords + 1);
+
+ FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++))
+ {
+ cw_buf[j] = cw_buf[dw_offset]; move16();
+ }
+
+ rs16_enc(cw_buf, codeword_length, hd, mode, 1);
+
+ cw_offset = add(cw_offset, codeword_length);
+
+ /* encoding of remaining data words */
+ hd = hamming_distance_by_mode1[mode]; move16();
+ redundancy_nibbles = sub(hd, 1);
+
+ FOR (i = 1; i < n_codewords; i++)
+ {
+ codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i);
+
+ assert(codeword_length == (2 * slot_bytes - i - 1) / n_codewords + 1);
+ FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++))
+ {
+ cw_buf[cw_offset + j] = cw_buf[dw_offset]; move16();
+ }
+
+ rs16_enc(cw_buf + cw_offset, codeword_length, hd, mode, sub(i, 6) < 0);
+
+ cw_offset = add(cw_offset, codeword_length);
+ }
+
+ assert(cw_offset == 2 * slot_bytes && dw_offset == 2 * slot_bytes);
+
+ fec_interleave_pack(iobuf, cw_buf, add(slot_bytes, slot_bytes), n_codewords);
+
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode,
+ Word16 signal_mode)
+/* expects (data polynomial) * x^(hamming_distance - 1) in iobuf */
+{
+
+ Dyn_Mem_Deluxe_In(
+ UWord8 const *gp;
+ UWord8 shift_buffer[RS16_CW_LEN_MAX + 1], lc;
+ int i, j, deg_gp;
+ );
+
+ basop_memset(shift_buffer, 0, sizeof(shift_buffer));
+ gp = rs16_gp_by_hd[hamming_distance]; move16();
+ deg_gp = sub(hamming_distance, 1);
+
+ IF (sub(hamming_distance, 1) > 0)
+ {
+ assert(codeword_length > deg_gp);
+
+ /* initialize redundancy part to zero */
+ basop_memset(iobuf, 0, deg_gp);
+
+ /* initialize shift_buffer */
+ basop_memmove(shift_buffer + 1, iobuf + codeword_length - deg_gp, deg_gp);
+
+ /* calculate remainder */
+ FOR (i = codeword_length - deg_gp - 1; i >= 0; i--)
+ {
+ shift_buffer[0] = iobuf[i]; move16();
+ lc = (UWord8)shl(shift_buffer[deg_gp], 4); move16();
+ FOR (j = deg_gp - 1; j >= 0; j--)
+ {
+ shift_buffer[j + 1] = GF16_ADD(shift_buffer[j], GF16_MUL0(gp[j], lc)); move16();
+ }
+ }
+
+ /* add remainder to shifted data polynomial */
+ FOR (i = 0; i < deg_gp; i++)
+ {
+ iobuf[i] = shift_buffer[i + 1]; move16();
+ }
+
+ /* add signaling polynomial */
+ IF (signal_mode)
+ {
+ assert(codeword_length > EP_SIG_POLY_DEG);
+ FOR (i = 0; i <= EP_SIG_POLY_DEG; i++)
+ {
+ iobuf[i] = GF16_ADD(iobuf[i], sig_polys[fec_mode - 1][i]); move16();
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 out_offset, cw_offset, codeword_length;
+ int i, j;
+ );
+
+ out_offset = 0; move16();
+ cw_offset = 0; move16();
+
+ /* initialize output buffer to zero */
+ basop_memset(out, 0, shr(n_nibbles, 1));
+
+ /* interleave and pack codewords */
+ FOR (i = 0; i < n_codewords; i++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_nibbles, i);
+
+ assert(codeword_length == (n_nibbles - i - 1) / n_codewords + 1);
+ FOR (j = 0; j < codeword_length; j++)
+ {
+ out_offset = add(DEPR_i_mult(j, n_codewords), i);
+ out_offset = sub(n_nibbles, add(out_offset, 1));
+ out[out_offset >> 1] =
+ (UWord8)s_or(out[out_offset >> 1], shl(in[cw_offset], shl(s_and(out_offset, 1), 2))); move16();
+ cw_offset = add(cw_offset, 1);
+ }
+ }
+
+ assert(cw_offset == n_nibbles);
+ Dyn_Mem_Deluxe_Out();
+}
+
+/* Decoder */
+FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *obuf, Word16 data_bytes, UWord8 *cw_buf,
+ Word16 slot_bytes, Word16 pc_split, int *bfi)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 i;
+ Word16 n_crc1, n_crc2;
+ Word16 cw_buf_len;
+ Word16 tmp_epmr;
+ );
+
+ n_crc1 = crc1_bytes_by_mode1[mode]; move16();
+ if (sub(slot_bytes, 40) == 0)
+ {
+ n_crc1 = crc1_bytes_by_mode0[mode]; move16();
+ }
+
+ n_crc2 = 0; move16();
+ if (pc_split > 0)
+ {
+ n_crc2 = crc2_bytes_by_mode[mode]; move16();
+ }
+
+ assert(n_crc1 == (slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]));
+ assert(n_crc2 == ((pc_split > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0));
+
+ cw_buf_len = 2 * (data_bytes + n_crc1 + n_crc2);
+
+ IF (sub(mode, 1))
+ {
+ /* reverse bit-swap */
+ dw0_bitswap(cw_buf, mode, slot_bytes);
+ tmp_epmr = dw0_get_epmr(cw_buf, mode, slot_bytes);
+
+ IF (crc1(cw_buf + shl(add(n_crc1, n_crc2), 1), sub(shl(data_bytes, 1), pc_split), tmp_epmr, cw_buf, n_crc1, 1))
+ {
+ *bfi = 1; move32();
+
+ Dyn_Mem_Deluxe_Out();
+ return;
+ }
+ else
+ {
+ *epmr = tmp_epmr;
+ }
+ }
+
+ test();
+ IF (pc_split > 0 && sub(*bfi, 2) != 0)
+ {
+ IF (crc2(cw_buf + sub(shl(add(data_bytes, add(n_crc1, n_crc2)), 1), pc_split), pc_split,
+ cw_buf + shl(n_crc1, 1), n_crc2, 1))
+ {
+ *bfi = 2; move32();
+ }
+ }
+
+ FOR (i = 0; i < data_bytes; i++)
+ {
+ obuf[i] = (UWord8)s_or(cw_buf[cw_buf_len - 2 * i - 1], shl(cw_buf[cw_buf_len - 2 * i - 2], 4)); move16();
+ }
+ Dyn_Mem_Deluxe_Out();
+}
+
+int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw,
+ int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord8 *my_scratch;
+ UWord8 *cw_buf;
+ UWord8 *array_of_trust;
+ Word16 i, j;
+ Word16 cw_offset, dw_offset;
+ Word16 n_codewords, redundancy_nibbles, codeword_length;
+ Word16 mode, error_report;
+ Word16 n_crc;
+ Word16 first_bad_cw;
+ Word16 pc_split;
+ );
+
+ IF (*bfi == 1)
+ {
+ Dyn_Mem_Deluxe_Out();
+ return ERROR_REPORT_BEC_MASK;
+ }
+
+ if (slot_bytes < FEC_SLOT_BYTES_MIN || slot_bytes > FEC_SLOT_BYTES_MAX)
+ {
+ *bfi = 1;
+ return ERROR_REPORT_BEC_MASK;
+ }
+
+ my_scratch = (UWord8 *)scratch; move32();
+ cw_buf = my_scratch; move32();
+ my_scratch += 2 * slot_bytes;
+
+ IF (ccc_flag == 0)
+ {
+ *be_bp_left = -1; move16();
+ *be_bp_right = -1; move16();
+ }
+
+ n_codewords = get_n_codewords(slot_bytes);
+
+ array_of_trust = my_scratch; move32();
+ my_scratch += n_codewords;
+
+ /* extract and de-interleave nibbles */
+ fec_deinterleave_unpack(cw_buf, iobuf, 2 * slot_bytes, n_codewords);
+
+ /* mode detection and error correction */
+ mode = rs16_detect_and_correct(cw_buf, 2 * slot_bytes, n_codewords, epmr, &error_report, bfi, array_of_trust,
+ ccc_flag, n_pccw, (void *)my_scratch);
+
+ /* for normal slots the maximal number of bit errors is limited */
+ test();
+#ifndef APPLY_MAX_ERRORS
+ IF (sub(slot_bytes, 40) == 0 && mode > 0)
+ {
+ IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[mode]) > 0)
+ {
+ error_report &= ERROR_REPORT_BEC_MASK;
+ mode = -1; move16();
+ *bfi = 1; move32();
+ }
+ ELSE
+ {
+ IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[2]) > 0)
+ {
+ error_report &= ~ERROR_REPORT_EP2_OK;
+ }
+ IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[3])>0)
+ {
+ error_report &= ~ERROR_REPORT_EP3_OK;
+ }
+ }
+ }
+#endif
+
+ IF (sub(*bfi, 1) == 0)
+ {
+ *data_bytes = 0; move16();
+
+ Dyn_Mem_Deluxe_Out();
+ return error_report;
+ }
+
+ /* initialization for decoding */
+ *data_bytes = fec_get_data_size(mode, ccc_flag, slot_bytes); move32();
+ pc_split = fec_get_n_pc(mode, *n_pccw, slot_bytes);
+ n_crc = get_total_crc_size(slot_bytes, mode, pc_split);
+
+ /* decoding of first code word */
+ redundancy_nibbles = sub(hamming_distance_by_mode0[mode], 1);
+ codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0);
+
+ dw_offset = 0; move16();
+ cw_offset = 0; move16();
+
+ FOR (j = redundancy_nibbles; j < codeword_length; j++)
+ {
+ cw_buf[dw_offset++] = cw_buf[j]; move16();
+ }
+ cw_offset = add(cw_offset, codeword_length);
+
+ /* decoding of remaining code words */
+ redundancy_nibbles = sub(hamming_distance_by_mode1[mode], 1);
+
+ FOR (i = 1; i < n_codewords; i++)
+ {
+ codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i);
+
+ FOR (j = redundancy_nibbles; j < codeword_length; j++)
+ {
+ cw_buf[dw_offset++] = cw_buf[j + cw_offset]; move16();
+ }
+
+ cw_offset = add(cw_offset, codeword_length);
+ }
+
+ assert(2 * (*data_bytes + n_crc) == dw_offset && 2 * slot_bytes == cw_offset);
+
+ /* data postproc: hash validation and re-ordering */
+
+ fec_data_postproc(mode, epmr, iobuf, *data_bytes, cw_buf, slot_bytes, pc_split, bfi);
+
+ IF (sub(*bfi, 1) == 0)
+ {
+ *data_bytes = 0; move32();
+ error_report &= ERROR_REPORT_BEC_MASK;
+ Dyn_Mem_Deluxe_Out();
+ return error_report;
+ }
+
+ IF (*bfi == 2)
+ {
+ first_bad_cw = 0; move16();
+ array_of_trust[*n_pccw] = 0; move16();
+ WHILE (array_of_trust[first_bad_cw] != 0)
+ {
+ first_bad_cw = add(first_bad_cw, 1);
+ }
+ IF (sub(first_bad_cw, *n_pccw) == 0)
+ {
+ /* this is the case when CRC failed */
+ *be_bp_left = 0; move16();
+ }
+ ELSE
+ {
+ *be_bp_left = extract_l(L_mult0(fec_get_n_pc(mode, first_bad_cw, slot_bytes), 4)); move16();
+ }
+
+ FOR (i = *n_pccw - 1; i >= 0; i--)
+ {
+ if (!array_of_trust[i])
+ {
+ BREAK;
+ }
+ }
+ IF (i < 0)
+ {
+ i = sub(*n_pccw, 1);
+ }
+ *be_bp_right = sub(extract_l(L_mult0(fec_get_n_pc(mode, i+1, slot_bytes), 4)), 1); move16();
+
+ }
+
+ IF (ccc_flag == 0)
+ {
+ *n_pc = pc_split; move16();
+ *m_fec = mode; move16();
+ }
+
+
+ Dyn_Mem_Deluxe_Out();
+ return error_report;
+}
+
+FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 in_offset, out_offset, codeword_length;
+ int i, j;
+ );
+
+ in_offset = 0; move16();
+ out_offset = 0; move16();
+
+ /* unpack nibbles in input buffer and deinterleave codewords */
+ FOR (i = 0; i < n_codewords; i++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_nibbles, i);
+ FOR (j = 0; j < codeword_length; (j++, out_offset++))
+ {
+ in_offset = add(DEPR_i_mult(j, n_codewords), i);
+ in_offset = sub(n_nibbles, add(in_offset, 1));
+ out[out_offset] = (UWord8)s_and(shr(in[in_offset >> 1], shl(s_and(in_offset, 1), 2)), 15); move16();
+ }
+ }
+
+ assert(out_offset == n_nibbles);
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp,
+ UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb)
+{
+ Dyn_Mem_Deluxe_In(
+ int epmr_lowest_risk_exp;
+ int start, inc, i, n_candidates;
+ int first_codeword_length;
+ int mode_counter;
+ Word16 epmr;
+ );
+
+ epmr_lowest_risk_exp = 0;
+ first_codeword_length = get_codeword_length(n_codewords, n_symb, 0);
+ start = 2;
+ inc = 1;
+ n_candidates = 0;
+
+ /* test if first code word decodes in mode 0 or 1 without error correction */
+ test();
+ IF (s_or(syndromes[SYNDROME_IDX(0, 0)], syndromes[SYNDROME_IDX(0, 0) + 1]) == 0 ||
+ s_or(syndromes[SYNDROME_IDX(1, 0)], syndromes[SYNDROME_IDX(1, 0) + 1]) == 0)
+ {
+ epmr_lowest_risk_exp = risk_table_f[1][0].exponent; move16();
+ }
+ /* test if first code word decodes in mode 2 or 3 with lower risk */
+ IF (sub(deg_elp[DEG_ELP_IDX(2, 0)], t[2]) <= 0)
+ {
+ IF (add(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]].exponent, 8) <= 0)
+ {
+ n_candidates++;
+ start = 2;
+ }
+ }
+
+ IF (sub(deg_elp[DEG_ELP_IDX(3, 0)], t[3]) <= 0)
+ {
+ IF (add(risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]].exponent, 8) <= 0)
+ {
+ n_candidates++;
+ start = 3;
+ }
+ }
+
+ IF (sub(n_candidates, 1) > 0)
+ {
+ /* decide on order if mode 2 and 3 are considered */
+ IF (simple_float_cmp(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]], risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]]) <
+ 0)
+ {
+ start = 2;
+ inc = 1;
+ }
+ ELSE
+ {
+ start = 3;
+ inc = -1;
+ }
+ }
+
+ FOR ((mode_counter = start, i = 0); i < n_candidates; (mode_counter += inc, i++))
+ {
+ IF (sub(risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent, epmr_lowest_risk_exp) < 0)
+ {
+ IF (!rs16_factorize_elp(err_pos + ERR_POS_IDX(mode_counter, 0), elp + ELP_IDX(mode_counter, 0),
+ deg_elp[DEG_ELP_IDX(mode_counter, 0)], sub(first_codeword_length, 1)))
+ {
+ /* code word is decodable with error correction */
+ epmr_lowest_risk_exp = risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent;
+
+ rs16_calculate_errors(err_symb + ERR_SYMB_IDX(mode_counter, 0), err_pos + ERR_POS_IDX(mode_counter, 0),
+ syndromes + SYNDROME_IDX(mode_counter, 0), deg_elp[DEG_ELP_IDX(mode_counter, 0)],
+ t[mode_counter]);
+
+ FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode_counter, 0)]; i++)
+ {
+ cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]] = GF16_ADD(
+ cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]], err_symb[ERR_SYMB_IDX(mode_counter, 0) + i]);
+ }
+ BREAK;
+ }
+ }
+ }
+
+ epmr = cw0_get_epmr(cw0, sub(first_codeword_length, 1));
+
+ IF (add(epmr_lowest_risk_exp, 16) > 0)
+ {
+ epmr = add(epmr, 4); move16();
+ }
+ IF (add(epmr_lowest_risk_exp, 8) > 0)
+ {
+ epmr = add(epmr, 4); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return epmr;
+}
+
+FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report,
+ int *bfi, UWord8 *array_of_trust, int ccc_flag, Word16 *n_pccw, void *scratch)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord8 * syndromes;
+ UWord8 * elp;
+ UWord8 * err_pos;
+ UWord8 * err_symb;
+ Word8 t[FEC_N_MODES];
+ Word8 * deg_elp;
+ UWord8 * my_scratch;
+ UWord8 blacklist[FEC_N_MODES];
+ UWord8 const *hamming_distance;
+
+ Word16 i, cw_counter, mode_counter, cw_offset;
+ Word16 codeword_length;
+ Word16 mode;
+ Word16 mode_candidates[4];
+ Word16 mode_broken[4];
+ Word16 error_report_ep_ok[4];
+ Word16 n_mode_candidates;
+ Word16 broken_cw, n_broken_cw;
+ Word16 j, idx_min;
+ Word16 n_pccw0;
+ simple_float val_min_f;
+ Word16 tmp;
+ Word16 epmr_position;
+ simple_float dec_risk_f[FEC_N_MODES];
+ simple_float risk_min_f;
+ simple_float ep_risk_thresh;
+
+ int epmr_dec_fail_increment;
+
+ void (*syndr_calc[3])(UWord8 *, UWord8 *, int);
+ );
+
+ /* initialization */
+ blacklist[0] = 0; move16();
+ blacklist[1] = 0; move16();
+ blacklist[2] = 0; move16();
+ blacklist[3] = 0; move16();
+ mode_broken[0] = 0; move16();
+ mode_broken[1] = 0; move16();
+ mode_broken[2] = 0; move16();
+ mode_broken[3] = 0; move16();
+ error_report_ep_ok[0] = ERROR_REPORT_EP1_OK;
+ error_report_ep_ok[1] = ERROR_REPORT_EP2_OK;
+ error_report_ep_ok[2] = ERROR_REPORT_EP3_OK;
+ error_report_ep_ok[3] = ERROR_REPORT_EP4_OK;
+ my_scratch = (UWord8 *)scratch;
+ hamming_distance = &hamming_distance_by_mode0[1];
+ mode = -1; move16();
+ n_mode_candidates = 0; move16();
+ risk_min_f.mantissa = SIMPLE_FLOAT_1_MANTISSA; move16();
+ risk_min_f.exponent = 0; move16();
+
+ IF (n_symb <= 80)
+ {
+ ep_risk_thresh.mantissa = EP_RISK_THRESH_NS_M; move16();
+ ep_risk_thresh.exponent = EP_RISK_THRESH_NS_E; move16();
+ }
+ ELSE
+ {
+ ep_risk_thresh.mantissa = EP_RISK_THRESH_OS_M; move16();
+ ep_risk_thresh.exponent = EP_RISK_THRESH_OS_E; move16();
+ }
+
+ syndr_calc[0] = &rs16_calculate_two_syndromes;
+ syndr_calc[1] = &rs16_calculate_four_syndromes;
+ syndr_calc[2] = &rs16_calculate_six_syndromes;
+
+ FOR (i = 0; i < FEC_N_MODES; i++)
+ {
+ t[i] = (Word8)shr(sub(hamming_distance[i], 1), 1); move16();
+ }
+
+ syndromes = my_scratch;
+ my_scratch += FEC_TOTAL_SYNDROME_SIZE;
+ elp = my_scratch;
+ my_scratch += FEC_TOTAL_ELP_SIZE;
+ err_pos = my_scratch;
+ my_scratch += FEC_TOTAL_ERR_POS_SIZE;
+ err_symb = my_scratch;
+ my_scratch += FEC_TOTAL_ERROR_SIZE;
+ deg_elp = (Word8 *)my_scratch;
+ my_scratch += FEC_TOTAL_DEG_ELP_SIZE;
+
+ *error_report = 0; move16();
+ *bfi = 0; move32();
+
+ /* mode detection (stage 1) */
+ codeword_length = get_codeword_length(n_codewords, n_symb, 0);
+
+ epmr_position = sub(codeword_length, 1);
+
+ rs16_calculate_two_syndromes(syndromes + SYNDROME_IDX(0, 0), iobuf, sub(codeword_length, 1));
+
+ IF (s_or(syndromes[0 + SYNDROME_IDX(0, 0)], syndromes[1 + SYNDROME_IDX(0, 0)]) == 0)
+ {
+
+ /* data validation for fec mode 1 */
+ *epmr = cw0_get_epmr(iobuf, epmr_position);
+
+ dw0_bitswap(iobuf + 2, 1, n_symb / 2);
+
+ IF (!crc1(iobuf + 8, sub(n_symb, 8), *epmr, iobuf + 2, 3, 1))
+ {
+ mode = 0; move16();
+ *error_report |= ERROR_REPORT_ALL_OK;
+ Dyn_Mem_Deluxe_Out();
+ return add(mode, 1);
+ }
+ ELSE
+ {
+ /* reverse bit swap */
+ dw0_bitswap(iobuf + 2, 1, n_symb / 2);
+
+ *epmr = add(*epmr, 4); move16();
+ }
+ }
+
+ blacklist[0] = 1; move16();
+
+ /* mode detection (stage 2) */
+
+ /* calculate syndromes of code words 0 to 5 and modes 1 to 3 */
+ cw_offset = 0; move16();
+
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter);
+
+ rs16_calculate_six_syndromes(syndromes + SYNDROME_IDX(1, cw_counter), iobuf + cw_offset,
+ sub(codeword_length, 1));
+
+ cw_offset = add(cw_offset, codeword_length);
+
+ FOR (mode_counter = FEC_N_MODES - 1; mode_counter >= 1; mode_counter--)
+ {
+ FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++)
+ {
+ syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i] = GF16_ADD(
+ syndromes[SYNDROME_IDX(1, cw_counter) + i], sig_poly_syndr[mode_counter][i]); move16();
+ }
+ }
+ }
+
+ /* check for valid code words */
+ FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++)
+ {
+ n_broken_cw = 0;
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ broken_cw = 0;
+ FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++)
+ {
+ broken_cw = s_or(broken_cw, syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i]); move16();
+ }
+ IF (broken_cw != 0)
+ {
+ n_broken_cw = add(n_broken_cw, 1);
+ }
+ }
+
+ IF (n_broken_cw == 0)
+ {
+ mode = mode_counter; move16();
+ cw_offset = 0; move16();
+
+ *epmr = cw0_get_epmr(iobuf, epmr_position);
+
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter);
+ FOR (i = 0; i <= EP_SIG_POLY_DEG; i++)
+ {
+ iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]);
+ }
+ cw_offset = add(cw_offset, codeword_length);
+ }
+ }
+ }
+
+ IF (mode < 0) /* mode hasn't been detected so far -> errors occurred in transmission */
+ {
+ /* calculate error locator polynomials for code words 0 to 5 */
+ FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++)
+ {
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] = rs16_calculate_elp(
+ elp + ELP_IDX(mode_counter, cw_counter), syndromes + SYNDROME_IDX(mode_counter, cw_counter),
+ t[mode_counter]); move16();
+ IF (sub(deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)], t[mode_counter]) > 0)
+ {
+ blacklist[mode_counter] = 1; move16();
+ BREAK;
+ }
+ }
+ }
+
+ /* risk analysis for mode candidate selection */
+ FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++)
+ {
+ dec_risk_f[mode_counter].mantissa = SIMPLE_FLOAT_1_MANTISSA; move16();
+ dec_risk_f[mode_counter].exponent = 0; move16();
+
+ IF (blacklist[mode_counter] == 0)
+ {
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ dec_risk_f[mode_counter] = simple_float_mul(
+ dec_risk_f[mode_counter],
+ risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)]]); move16();
+ }
+
+ IF (simple_float_cmp(dec_risk_f[mode_counter], ep_risk_thresh) <= 0)
+ {
+ mode_candidates[n_mode_candidates++] = mode_counter; move16();
+ }
+
+ IF (simple_float_cmp(dec_risk_f[mode_counter], risk_min_f) < 0)
+ {
+ risk_min_f = dec_risk_f[mode_counter]; move16();
+ }
+ }
+ }
+ assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3
+
+ /* sort mode candidates by risk */
+ FOR (i = 0; i < n_mode_candidates; i++)
+ {
+ idx_min = i; move16();
+ val_min_f = dec_risk_f[mode_candidates[i]]; move16();
+
+ FOR (j = i + 1; j < n_mode_candidates; j++)
+ {
+ IF (simple_float_cmp(dec_risk_f[mode_candidates[j]], val_min_f) < 0)
+ {
+ val_min_f = dec_risk_f[mode_candidates[j]]; move16();
+ idx_min = j; move16();
+ }
+ }
+
+ IF (sub(idx_min, i) > 0)
+ {
+ tmp = mode_candidates[i]; move16();
+ mode_candidates[i] = mode_candidates[idx_min]; move16();
+ mode_candidates[idx_min] = tmp; move16();
+ }
+ }
+
+ /* try out candidate modes */
+ FOR (i = 0; i < n_mode_candidates; i++)
+ {
+ mode = mode_candidates[i]; move16();
+
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter);
+
+ IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)])
+ {
+ IF (rs16_factorize_elp(err_pos + ERR_POS_IDX(mode, cw_counter), elp + ELP_IDX(mode, cw_counter),
+ deg_elp[DEG_ELP_IDX(mode, cw_counter)], sub(codeword_length, 1)))
+ {
+ /* elp did not split into distinct linear factors or error position was out of range */
+ mode = -1; move16();
+ BREAK;
+ }
+ }
+ }
+ IF (mode > 0)
+ {
+ /* decodable mode with lowest risk has been found */
+ BREAK;
+ }
+ }
+
+ IF (mode < 0)
+ {
+ /* no decodable mode has been found */
+ *error_report = ERROR_REPORT_BEC_MASK; move16();
+ *bfi = 1; move32();
+ mode = -1; move16();
+
+ *epmr = fec_estimate_epmr_from_cw0(iobuf, t, syndromes, elp, deg_elp, err_pos, err_symb, n_codewords,
+ n_symb);
+
+ Dyn_Mem_Deluxe_Out();
+ return mode;
+ }
+
+ /* perform error correction */
+ cw_offset = 0; move16();
+ *error_report = 0; move16();
+ FOR (cw_counter = 0; cw_counter < 6; cw_counter++)
+ {
+ codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter);
+
+ IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)])
+ {
+ rs16_calculate_errors(
+ err_symb + ERR_SYMB_IDX(mode, cw_counter), err_pos + ERR_POS_IDX(mode, cw_counter),
+ syndromes + SYNDROME_IDX(mode, cw_counter), deg_elp[DEG_ELP_IDX(mode, cw_counter)], t[mode]);
+
+ /* correct errors and sum up number of corrected bits */
+ FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode, cw_counter)]; i++)
+ {
+ iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset] =
+ GF16_ADD(iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset],
+ err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]);
+ *error_report = add(*error_report,
+ rs16_bit_count_table[err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]]); move16();
+ }
+
+ FOR (i = 0; i < mode; i ++)
+ {
+ IF(deg_elp[DEG_ELP_IDX(mode, cw_counter)] > i)
+ {
+ mode_broken[i] = 1;
+ }
+ }
+ }
+
+ FOR (i = 0; i <= EP_SIG_POLY_DEG; i++)
+ {
+ iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]);
+ }
+ cw_offset = add(cw_offset, codeword_length);
+ }
+
+ /* set epmr according to risk value of cw0 */
+ epmr_dec_fail_increment = 8;
+
+ IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 8) <= 0)
+ {
+ epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4);
+ }
+ IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 16) <= 0)
+ {
+ epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4);
+ }
+
+ *epmr = cw0_get_epmr(iobuf, epmr_position) + epmr_dec_fail_increment;
+ }
+
+ /* mode has been successfully detected -> now check and try to correct remaining code words*/
+ *n_pccw = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag);
+ IF (ccc_flag == 0)
+ {
+ n_pccw0 = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag);
+ *n_pccw = n_pccw0;
+ }
+ ELSE
+ {
+ n_pccw0 = 0;
+ }
+
+ FOR (cw_counter = 6; cw_counter < n_codewords; cw_counter++)
+ {
+ /* usual error correction scheme: syndromes -> elp's, errors, etc. */
+ codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter);
+ array_of_trust[n_codewords - 1 - cw_counter] = 1; move16();
+
+ syndr_calc[sub(t[mode], 1)](syndromes, iobuf + cw_offset, sub(codeword_length, 1));
+
+ deg_elp[0] = rs16_calculate_elp(elp, syndromes, t[mode]); move16();
+
+ FOR (i = 0; i < mode; i ++)
+ {
+ IF(deg_elp[0] > i)
+ {
+ mode_broken[i] = 1;
+ }
+ }
+ IF (sub(deg_elp[0], t[mode]) > 0)
+ {
+ FOR (i = 0; i < 4; i ++)
+ {
+ mode_broken[i] = 1;
+ }
+ cw_offset = add(cw_offset, codeword_length);
+ IF (cw_counter < n_codewords - n_pccw0)
+ {
+ *error_report = ERROR_REPORT_BEC_MASK; move16();
+ mode = -1; move16();
+ *bfi = 1; move32();
+
+ BREAK;
+ }
+ ELSE
+ {
+ *bfi = 2; move32();
+ array_of_trust[n_codewords - 1 - cw_counter] = 0; move16();
+ CONTINUE;
+ }
+ }
+
+ IF (deg_elp[0])
+ {
+ IF (rs16_factorize_elp(err_pos, elp, deg_elp[0], sub(codeword_length, 1)))
+ {
+ cw_offset = add(cw_offset, codeword_length);
+ FOR (i = 0; i < 4; i ++)
+ {
+ mode_broken[i] = 1;
+ }
+ IF (add(n_pccw0, sub(cw_counter, n_codewords)) < 0)
+ {
+ *error_report = ERROR_REPORT_BEC_MASK; move16();
+ mode = -1; move16();
+ *bfi = 1; move32();
+
+ BREAK;
+ }
+ ELSE
+ {
+ *bfi = 2; move32();
+ array_of_trust[n_codewords - 1 - cw_counter] = 0; move16();
+ CONTINUE;
+ }
+ }
+
+ rs16_calculate_errors(err_symb, err_pos, syndromes, deg_elp[0], t[mode]);
+
+ /* correct errors and sum up number of corrected bits */
+ FOR (i = 0; i < deg_elp[0]; i++)
+ {
+ iobuf[err_pos[i] + cw_offset] = GF16_ADD(iobuf[err_pos[i] + cw_offset], err_symb[i]);
+ *error_report = add(*error_report, rs16_bit_count_table[err_symb[i]]);
+ }
+ }
+ cw_offset = add(cw_offset, codeword_length);
+ if (add(risk_table_f[mode][deg_elp[0]].exponent, 16) > 0)
+ {
+ array_of_trust[n_codewords - 1 - cw_counter] = 0; move16();
+ }
+ }
+
+ *error_report &= ERROR_REPORT_BEC_MASK;
+ FOR (i = 0; i < 4; i ++)
+ {
+ IF (!mode_broken[i])
+ {
+ *error_report |= error_report_ep_ok[i];
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ IF (mode >= 0)
+ {
+ return add(mode, 1);
+ }
+
+ return -1;
+}
+
+FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg)
+{
+ Dyn_Mem_Deluxe_In(
+ int i;
+ UWord8 buffer[15];
+ );
+
+ assert(cw_poly_deg >= 12);
+
+ FOR (i = 0; i <= cw_poly_deg; i++)
+ {
+ buffer[i] = cw[i]; move16();
+ }
+
+ syndromes[0] = buffer[0]; move16();
+ syndromes[1] = buffer[0]; move16();
+ syndromes[2] = buffer[0]; move16();
+ syndromes[3] = buffer[0]; move16();
+ syndromes[4] = buffer[0]; move16();
+ syndromes[5] = buffer[0]; move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[1], 96)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[1], 192)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[2], 112)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[2], 240)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[3], 16)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[3], 128)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[4], 96)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[4], 160)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[5], 112)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[5], 16)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[6], 16)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[6], 192)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[7], 96)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[7], 240)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[8], 112)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[8], 128)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[9], 16)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[9], 160)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[10], 96)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[10], 16)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[11], 112)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[11], 192)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[12], 16)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[12], 240)); move16();
+
+ IF (sub(cw_poly_deg, 13) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[13], 96)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[13], 128)); move16();
+ }
+
+ IF (sub(cw_poly_deg, 14) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16();
+ syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[14], 112)); move16();
+ syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[14], 160)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg)
+{
+ Dyn_Mem_Deluxe_In(
+ int i;
+ UWord8 buffer[15];
+ );
+
+ assert(cw_poly_deg >= 12);
+
+ FOR (i = 0; i <= cw_poly_deg; i++)
+ {
+ buffer[i] = cw[i]; move16();
+ }
+
+ syndromes[0] = buffer[0]; move16();
+ syndromes[1] = buffer[0]; move16();
+ syndromes[2] = buffer[0]; move16();
+ syndromes[3] = buffer[0]; move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16();
+
+ IF (sub(cw_poly_deg, 13) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16();
+ }
+
+ IF (sub(cw_poly_deg, 14) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16();
+ syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16();
+ syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg)
+{
+ Dyn_Mem_Deluxe_In(
+ int i;
+ UWord8 buffer[15];
+ );
+
+ assert(cw_poly_deg >= 12);
+
+ FOR (i = 0; i <= cw_poly_deg; i++)
+ {
+ buffer[i] = cw[i]; move16();
+ }
+
+ syndromes[0] = buffer[0]; move16();
+ syndromes[1] = buffer[0]; move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16();
+
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16();
+
+ IF (sub(cw_poly_deg, 13) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16();
+ }
+
+ IF (sub(cw_poly_deg, 14) >= 0)
+ {
+ syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16();
+ syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 t)
+/* calculates error locator polynomial vie Petterson's algorithm */
+{
+ Dyn_Mem_Deluxe_In(
+ Word8 ret;
+ UWord8 det, det_inv, aux, all_s, *s;
+ UWord8 s22, s33, s44, s13, s14, s15;
+ UWord8 s23, s24, s25, s34, s35;
+ UWord8 a, b, c, d, e, f;
+ );
+
+ ret = 0; move16();
+ all_s = 0; move16();
+ s = syndromes; move16();
+ elp[0] = 1; move16();
+ basop_memset(elp + 1, 0, 3);
+
+ SWITCH (t)
+ {
+ case 3:
+ {
+ /* check for errors */
+ all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s_or(s[3], s_or(s[4], s[5])))));
+
+ IF (all_s == 0)
+ {
+ BREAK;
+ }
+
+ /* assume 3 errors */
+ s22 = GF16_MUL(s[1], s[1]);
+ s33 = GF16_MUL(s[2], s[2]);
+ s44 = GF16_MUL(s[3], s[3]);
+ s13 = GF16_MUL(s[0], s[2]);
+
+ det = GF16_ADD(GF16_ADD(GF16_MUL(s13, s[4]), GF16_MUL(s44, s[0])),
+ GF16_ADD(GF16_MUL(s22, s[4]), GF16_MUL(s33, s[2])));
+
+ IF (det)
+ {
+ det_inv = (UWord8)shl(gf16_inv_table[det], 4);
+
+ s14 = GF16_MUL(s[0], s[3]);
+ s15 = GF16_MUL(s[0], s[4]);
+
+ s23 = GF16_MUL(s[1], s[2]);
+ s24 = GF16_MUL(s[1], s[3]);
+ s25 = GF16_MUL(s[1], s[4]);
+
+ s34 = GF16_MUL(s[2], s[3]);
+ s35 = GF16_MUL(s[2], s[4]);
+
+ a = GF16_ADD(s35, s44) << 4;
+ b = GF16_ADD(s15, s33) << 4;
+ c = GF16_ADD(s13, s22) << 4;
+ d = GF16_ADD(s34, s25) << 4;
+ e = GF16_ADD(s23, s14) << 4;
+ f = GF16_ADD(s24, s33) << 4;
+
+ aux = GF16_ADD(GF16_ADD(GF16_MUL0(a, s[3]), GF16_MUL0(d, s[4])), GF16_MUL0(f, s[5]));
+ elp[3] = GF16_MUL0(aux, det_inv);
+
+ aux = GF16_ADD(GF16_ADD(GF16_MUL0(d, s[3]), GF16_MUL0(b, s[4])), GF16_MUL0(e, s[5]));
+ elp[2] = GF16_MUL0(aux, det_inv);
+
+ aux = GF16_ADD(GF16_ADD(GF16_MUL0(f, s[3]), GF16_MUL0(e, s[4])), GF16_MUL0(c, s[5]));
+ elp[1] = GF16_MUL0(aux, det_inv);
+
+ IF (elp[3] == 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 3; move16();
+ }
+ BREAK;
+ }
+
+ /* assume two errors */
+ det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1]));
+
+ IF (det)
+ {
+ det_inv = (UWord8)shl(gf16_inv_table[det], 4);
+
+ aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3]));
+ elp[1] = GF16_MUL0(aux, det_inv);
+
+ aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3]));
+ elp[2] = GF16_MUL0(aux, det_inv);
+
+ /* check remaining LSF relations */
+ aux = (UWord8)s_or(GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[2]), GF16_MUL(elp[1], s[3])), s[4]),
+ GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[3]), GF16_MUL(elp[1], s[4])), s[5]));
+
+ aux = (UWord8)s_or(aux, elp[2] == 0);
+
+ IF (aux != 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 2; move16();
+ }
+ BREAK;
+ }
+
+ /* assume one error */
+ IF (syndromes[0] != 0)
+ {
+ elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]);
+
+ /* check remaining LSF relations */
+ aux = (UWord8)s_or(s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3])),
+ s_or(GF16_ADD(GF16_MUL(elp[1], s[3]), s[4]), GF16_ADD(GF16_MUL(elp[1], s[4]), s[5])));
+
+ aux = (UWord8)s_or(aux, elp[1] == 0);
+
+ IF (aux != 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 1; move16();
+ }
+ BREAK;
+ }
+
+ ret = (Word8) add(t, 1);
+ BREAK;
+ }
+ case 2:
+ {
+ all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s[3])));
+
+ IF (all_s == 0)
+ {
+ BREAK;
+ }
+
+ /* assume two errors */
+ det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1]));
+
+ IF (det)
+ {
+ det_inv = (UWord8)shl(gf16_inv_table[det], 4);
+
+ aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3]));
+ elp[1] = GF16_MUL0(aux, det_inv);
+
+ aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3]));
+ elp[2] = GF16_MUL0(aux, det_inv);
+
+ IF (elp[2] == 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 2; move16();
+ }
+ BREAK;
+ }
+
+ /* assume one error */
+ IF (syndromes[0] != 0)
+ {
+ elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]);
+
+ /* check remaining LSF relation */
+ aux = (UWord8)s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3]));
+ aux = (UWord8)s_or(aux, elp[1] == 0);
+ IF (aux != 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 1; move16();
+ }
+ BREAK;
+ }
+
+ ret = (Word8) add(t, 1);
+ BREAK;
+ }
+ case 1:
+ {
+ all_s = (UWord8)s_or(s[0], s[1]);
+
+ IF (all_s == 0)
+ {
+ BREAK;
+ }
+
+ IF (syndromes[0] != 0)
+ {
+ elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]);
+ IF (elp[1] == 0)
+ {
+ ret = (Word8) add(t, 1);
+ }
+ ELSE
+ {
+ ret = 1; move16();
+ }
+ BREAK;
+ }
+
+ ret = (Word8) add(t, 1);
+ BREAK;
+ }
+ default: assert(0 && "calculating elp of this degree not implemented");
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return ret;
+}
+
+FEC_STATIC Word16 rs16_factorize_elp(UWord8 *err_pos, UWord8 *elp, Word16 deg_elp, Word16 max_pos)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord8 beta, gamma;
+ Word16 zeros, err_pos0, err_pos1, err_pos2, ret;
+ );
+
+ beta = 0; move16();
+ gamma = 0; move16();
+ zeros = 0; move16();
+ ret = 0; move16();
+
+ SWITCH (deg_elp)
+ {
+ case 0: BREAK;
+
+ case 1:
+ err_pos0 = gf16_log_g[elp[1]]; move16();
+ IF (sub(err_pos0, max_pos) > 0)
+ {
+ ret = 1; move16();
+ BREAK;
+ }
+
+ err_pos[0] = (UWord8)err_pos0; move16();
+ BREAK;
+
+ case 2:
+ zeros = rs16_elp_deg2_table[s_or(elp[1], shl(elp[2], 4))]; move16();
+ IF (zeros == 0)
+ {
+ Dyn_Mem_Deluxe_Out();
+ return 1;
+ }
+
+ err_pos0 = s_and(zeros, 15);
+ err_pos1 = s_and(shr(zeros, 4), 15);
+
+ IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0)
+ {
+ ret = 1; move16();
+ BREAK;
+ }
+
+ err_pos[0] = (UWord8)err_pos0; move16();
+ err_pos[1] = (UWord8)err_pos1; move16();
+ BREAK;
+
+ case 3:
+ /* beta = a*a + b, gamma = a*b + c */
+ beta = GF16_ADD(GF16_MUL(elp[1], elp[1]), elp[2]);
+ gamma = GF16_ADD(GF16_MUL(elp[1], elp[2]), elp[3]);
+ zeros = rs16_elp_deg3_table[beta | gamma << 4];
+
+ IF (zeros == 0)
+ /* elp does not split over GF(16) or has multiple zeros */
+ {
+ ret = 1; move16();
+ BREAK;
+ }
+
+ /* remove shift from zeros */
+ err_pos0 = GF16_ADD(s_and(zeros, 15), elp[1]);
+ err_pos1 = GF16_ADD(s_and(shr(zeros, 4), 15), elp[1]);
+ err_pos2 = GF16_ADD(s_and(shr(zeros, 8), 15), elp[1]);
+
+ IF (err_pos0 == 0 || err_pos1 == 0 || err_pos2 == 0)
+ {
+ test(); test();
+ Dyn_Mem_Deluxe_Out();
+ return 1;
+ }
+
+ err_pos0 = gf16_log_g[err_pos0];
+ err_pos1 = gf16_log_g[err_pos1];
+ err_pos2 = gf16_log_g[err_pos2];
+
+ IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0 || sub(err_pos2, max_pos) > 0)
+ {
+ test(); test();
+ ret = 1; move16();
+ BREAK;
+ }
+
+ err_pos[0] = (UWord8)err_pos0; move16();
+ err_pos[1] = (UWord8)err_pos1; move16();
+ err_pos[2] = (UWord8)err_pos2; move16();
+
+ BREAK;
+
+ default: assert(0 && "invalid degree in rs16_error_locator");
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return ret;
+}
+
+FEC_STATIC void rs16_calculate_errors(UWord8 *err_symb, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord8 det_inv;
+ UWord8 x0, x1, x2;
+ UWord8 x0sq, x1sq, x2sq;
+ UWord8 c0, c1, c2;
+ UWord8 s0, s1, s2;
+ UWord8 tmp;
+ );
+
+ assert(deg_elp <= t);
+ UNUSED(t);
+
+ SWITCH (deg_elp)
+ {
+ case 0: BREAK;
+
+ case 1:
+ err_symb[0] = GF16_MUL(gf16_g_pow[15 - err_pos[0]], syndromes[0]); move16();
+
+ BREAK;
+
+ case 2:
+ s0 = (UWord8)shl(syndromes[0], 4);
+ s1 = (UWord8)shl(syndromes[1], 4);
+
+ x0 = gf16_g_pow[err_pos[0]]; move16();
+ x1 = gf16_g_pow[err_pos[1]]; move16();
+
+ x0sq = GF16_MUL(x0, x0);
+ x1sq = GF16_MUL(x1, x1);
+
+ tmp = GF16_ADD(GF16_MUL(x0sq, x1), GF16_MUL(x1sq, x0));
+ det_inv = (UWord8)shl(gf16_inv_table[tmp], 4);
+
+ tmp = GF16_ADD(GF16_MUL0(x1sq, s0), GF16_MUL0(x1, s1));
+ err_symb[0] = GF16_MUL0(tmp, det_inv); move16();
+
+ tmp = GF16_ADD(GF16_MUL0(x0sq, s0), GF16_MUL0(x0, s1));
+ err_symb[1] = GF16_MUL0(tmp, det_inv); move16();
+
+ BREAK;
+
+ case 3:
+ s0 = (UWord8)shl(syndromes[0], 4);
+ s1 = (UWord8)shl(syndromes[1], 4);
+ s2 = (UWord8)shl(syndromes[2], 4);
+
+ x0 = gf16_g_pow[err_pos[0]]; move16();
+ x1 = gf16_g_pow[err_pos[1]]; move16();
+ x2 = gf16_g_pow[err_pos[2]]; move16();
+
+ x0sq = GF16_MUL(x0, x0);
+ x1sq = GF16_MUL(x1, x1);
+ x2sq = GF16_MUL(x2, x2);
+
+ tmp = GF16_MUL(GF16_ADD(x1, x0), GF16_ADD(x2, x0));
+ tmp = GF16_MUL(GF16_ADD(x2, x1), tmp);
+ det_inv = (UWord8)shl(gf16_inv_table[tmp], 4);
+
+ c0 = GF16_ADD(GF16_MUL(x1, x2sq), GF16_MUL(x2, x1sq));
+ c1 = GF16_ADD(x2sq, x1sq);
+ c2 = GF16_ADD(x2, x1);
+
+ err_symb[0] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16();
+
+ c0 = GF16_ADD(GF16_MUL(x0, x2sq), GF16_MUL(x2, x0sq));
+ c1 = GF16_ADD(x2sq, x0sq);
+ c2 = GF16_ADD(x2, x0);
+
+ err_symb[1] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16();
+
+ c0 = GF16_ADD(GF16_MUL(x0, x1sq), GF16_MUL(x1, x0sq));
+ c1 = GF16_ADD(x1sq, x0sq);
+ c2 = GF16_ADD(x1, x0);
+
+ err_symb[2] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16();
+
+ tmp = GF16_MUL0(err_symb[0], det_inv);
+ err_symb[0] = GF16_MUL(tmp, gf16_inv_table[x0]); move16();
+
+ tmp = GF16_MUL0(err_symb[1], det_inv);
+ err_symb[1] = GF16_MUL(tmp, gf16_inv_table[x1]); move16();
+
+ tmp = GF16_MUL0(err_symb[2], det_inv);
+ err_symb[2] = GF16_MUL(tmp, gf16_inv_table[x2]); move16();
+
+ BREAK;
+
+ default: assert(0 && "method not implemented\n"); BREAK;
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/* hash functions for data validation */
+
+/* hamming distance 4 */
+static const UWord32 crc14_mask[16] = {0, 17989, 35978, 51919, 71956, 89937, 103838, 119771,
+ 143912, 160877, 179874, 194791, 207676, 224633, 239542, 254451};
+
+/* hamming distance 4 */
+static const UWord32 crc22_mask[16] = {0, 4788009, 9576018, 14356859, 19152036, 23933837, 28713718, 33500639,
+ 33650273, 38304072, 43214899, 47867674, 52775621, 57427436, 62346391, 67001278};
+
+FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord32 const *mask;
+ int shift, i, fail;
+ UWord32 rem;
+ );
+
+ fail = 0; move16();
+ rem = 0; move16();
+
+ assert(hash_size > 0);
+
+ SWITCH (hash_size)
+ {
+ case 2:
+ shift = 14; move16();
+ mask = crc14_mask; move32();
+ BREAK;
+ case 3:
+ shift = 22; move16();
+ mask = crc22_mask; move32();
+ BREAK;
+ default:
+ shift = 0;
+ mask = 0;
+ assert(0 && "crc hash size not implemented");
+ }
+
+ /* data array contains 4-bit words */
+ FOR (i = data_size - 1; i >= 0; i--)
+ {
+ rem = UL_xor(UL_lshl(rem, 4), data[i]); move32();
+ rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32();
+ }
+
+ rem = UL_xor(UL_lshl(rem, 4), UL_lshl(epmr, 2));
+ rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32();
+
+ FOR (i = 0; i < 2 * hash_size - 1; i++)
+ {
+ rem = UL_lshl(rem, 4);
+ rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32();
+ }
+
+ rem = UL_xor(rem, UL_lshl((UWord32)epmr, shift)); move32();
+
+ IF (check)
+ {
+ /* test hash value */
+ FOR (i = 0; i < 2 * hash_size; i++)
+ {
+ fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32();
+ }
+ }
+ ELSE
+ {
+ /* write hash value */
+ for (i = 0; i < 2 * hash_size; i++)
+ {
+ hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32();
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return fail;
+}
+
+/* hamming distance = 4 */
+static const UWord32 crc16_mask[16] = {0, 107243, 190269, 214486, 289937, 380538, 428972, 469319,
+ 579874, 621513, 671263, 761076, 832947, 857944, 938638, 1044581};
+
+FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check)
+{
+ Dyn_Mem_Deluxe_In(
+ UWord32 const *mask;
+ int shift, i, fail;
+ UWord32 rem;
+ );
+
+ fail = 0; move16();
+ rem = 0; move16();
+
+ assert(hash_size > 0);
+
+ SWITCH (hash_size)
+ {
+ case 2:
+ shift = 16; move16();
+ mask = crc16_mask; move32();
+ BREAK;
+ default:
+ shift = 0;
+ mask = 0;
+ assert(0 && "crc hash size not implemented");
+ }
+
+ /* data array contains 4-bit words */
+ FOR (i = data_size - 1; i >= 0; i--)
+ {
+ rem = UL_xor(UL_lshl(rem, 4), data[i]); move32();
+ rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32();
+ }
+
+ FOR (i = 0; i < 2 * hash_size; i++)
+ {
+ rem = UL_lshl(rem, 4);
+ rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32();
+ }
+
+ IF (check)
+ {
+ /* test hash value */
+ FOR (i = 0; i < 2 * hash_size; i++)
+ {
+ fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32();
+ }
+ }
+ ELSE
+ {
+ /* write hash value */
+ FOR (i = 0; i < 2 * hash_size; i++)
+ {
+ hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32();
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return fail;
+}
+
+/* simple float implementation */
+
+FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2)
+{
+ Dyn_Mem_Deluxe_In(
+ simple_float rop;
+ Word32 aux;
+ );
+ aux = L_shr(L_mult0(op1.mantissa, op2.mantissa), 14);
+ rop.exponent = add(op1.exponent, op2.exponent);
+ IF (L_and(aux, 32768L))
+ {
+ aux = L_shr(aux, 1);
+ rop.exponent = add(rop.exponent, 1);
+ }
+ rop.mantissa = extract_l(aux);
+ Dyn_Mem_Deluxe_Out();
+ return rop;
+}
+
+/* Auxiliary */
+
+FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2)
+/* returns 1 if op1 > op2, 0 if op1 = op2, and -1 if op1 < op2 */
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 rval;
+ Word16 mdiff;
+ Word16 ediff;
+ );
+
+ rval = 0; move16();
+
+ ediff = sub(op1.exponent, op2.exponent);
+ mdiff = sub(op1.mantissa, op2.mantissa);
+
+ IF (ediff == 0)
+ {
+ if (mdiff > 0)
+ {
+ rval = 1;
+ }
+ if (mdiff < 0)
+ {
+ rval = -1;
+ }
+ }
+ ELSE
+ {
+ if (ediff > 0)
+ {
+ rval = 1;
+ }
+ if (ediff < 0)
+ {
+ rval = -1;
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return rval;
+}
+
+
diff --git a/lib_lc3plus/apply_global_gain_fx.c b/lib_lc3plus/apply_global_gain_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c5220f108f350b582504a5866f61e8d812b38cf
--- /dev/null
+++ b/lib_lc3plus/apply_global_gain_fx.c
@@ -0,0 +1,66 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off)
+{
+ Counter i;
+#ifdef ENABLE_HR_MODE
+ Word32 global_gain;
+#else
+ Word16 global_gain;
+#endif
+ Word16 global_gain_e;
+ Word32 tmp32;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processApplyGlobalGain_fx", sizeof(struct {
+ Counter i;
+ Word16 global_gain, global_gain_e;
+ Word32 tmp32;
+ }));
+#endif
+
+#ifdef ENABLE_HR_MODE
+ /* 1 / (28 * log 2) is 0x797D in Q18, L_shl_pos by 7 results in Q25 tmp32 */
+ /* round(2^31 / (28 * log10(2))) = 254778081 */
+ //tmp32 = L_shl_pos(Mpy_32_16_lc3plus(254778081, add(global_gain_idx, global_gain_off)), 9);
+ Word32 mh;
+ UWord16 ml;
+
+ Mpy_32_16_ss(254778081, add(global_gain_idx, global_gain_off), &mh, &ml);
+ tmp32 = L_shl_pos(mh, 9) | L_deposit_l((shr((Word16)ml, 7)) & 0x1ff);
+ move16();
+ /* Uses an argument in Q25 */
+ global_gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000));
+#else
+ tmp32 = L_shl_pos(L_mult0(add(global_gain_idx, global_gain_off), 0x797D), 7);
+ /* Uses an argument in Q25 */
+ global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000)));
+#endif
+ global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1);
+
+ FOR (i = 0; i < xLen; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ x[i] = Mpy_32_32_lc3plus(x[i], global_gain);
+#else
+ x[i] = Mpy_32_16_lc3plus(x[i], global_gain);
+#endif
+ move32();
+ }
+
+ *x_e = add(*x_e, global_gain_e); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c
new file mode 100644
index 0000000000000000000000000000000000000000..8092aa28e0d7c1af3d6388a01eccbf74e6aca193
--- /dev/null
+++ b/lib_lc3plus/ari_codec.c
@@ -0,0 +1,2465 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+
+typedef struct
+{
+ Word16 inv_bin;
+ Word16 numbytes;
+ Word16 c_bp;
+ Word16 c_bp_side;
+ Word16 bytes;
+ Word16 b_left;
+ Word16 b_right;
+ Word16 enc;
+ Word16 sim_dec;
+ Word16 bfi;
+ Word16 be_bp_left;
+ Word16 be_bp_right;
+} Pc_State_fx;
+
+typedef struct
+{
+ UWord32 ac_low_fx;
+ UWord32 ac_range_fx;
+ Word16 ac_cache_fx;
+ Word16 ac_carry_fx;
+ Word16 ac_carry_count_fx;
+} Encoder_State_fx;
+
+typedef struct
+{
+ UWord32 ac_low_fx;
+ UWord32 ac_range_fx;
+ UWord32 ac_help_fx;
+ Word16 BER_detect;
+ Pc_State_fx pc;
+} Decoder_State_fx;
+
+static void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side,
+ Decoder_State_fx *st_fx /* i/o: Decoder State */
+);
+
+static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec,
+ Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */
+);
+static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin,
+ Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */
+);
+
+static void ac_enc_init_fx(Encoder_State_fx *st_fx /* i/o: Encoder state */
+);
+
+static void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */
+);
+
+static void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits);
+
+static void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */
+ UWord32 cum_freq, /* i : Cumulative frequency up to symbol */
+ UWord32 sym_freq /* i : Symbol probability */
+);
+
+static Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */
+);
+
+static Word16 ac_decode_fx( /* o : Decoded cumulative frequency */
+ Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 pki);
+static Word16 ac_decode_tns_order( /* o : Decoded cumulative frequency */
+ Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 enable_lpc_weighting);
+static Word16 ac_decode_tns_coef( /* o : Decoded cumulative frequency */
+ Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 pki);
+static Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin,
+ Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ UWord32 cum_freq, /* i : Cumulative frequency */
+ UWord32 sym_freq /* i : Symbol frequency */
+);
+
+/*************************************************************************/
+
+# ifdef ENABLE_HR_MODE
+
+Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word32 xq[],
+ Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz,
+ Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode,
+ Word16 enable_lpc_weighting, Word8 *scratchBuffer)
+{
+ Word16 resbit, i1, i2;
+
+ Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits;
+ Word32 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp;
+ Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev;);
+
+ lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* size = 2 * lastnz */
+
+ /* Init */
+ a1_i = 0;
+ move16();
+ b1_i = 1;
+ move16();
+ bp = 0;
+ move16();
+ numResBitsEnc = 0;
+ move16();
+ nlsbs = 0;
+ move16();
+ ptr = bytes;
+ bp_side = bp_side_in;
+ move16();
+ mask_side = mask_side_in;
+ move16();
+
+ /*Start Encoding*/
+ ac_enc_init_fx(&st);
+
+ /* TNS data */
+ FOR (n = 0; n < tns_numfilters; n++)
+ {
+ IF (tns_order[n] > 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1],
+ ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]);
+ FOR (k = 0; k < tns_order[n]; k++)
+ {
+ ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]],
+ ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]);
+ }
+ }
+ }
+
+ IF (lsbMode == 0)
+ {
+
+ /*Main Loop through the 2-tuples*/
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+ IF (codingdata[1] < 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, 0,
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]);
+ }
+ ELSE IF (codingdata[1] == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+ ELSE IF (sub(codingdata[1], 1) == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]);
+ write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[a1_i], 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[b1_i], 1));
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+ ELSE
+ {
+ a1 = L_abs(xq[a1_i]);
+ b1 = L_abs(xq[b1_i]);
+ FOR (lev = 0; lev < codingdata[1]; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]);
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1));
+ }
+ lev1 = s_min(codingdata[1], 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /*end of the 2-tuples loop*/
+ }
+ ELSE
+ {
+ /*Main Loop through the 2-tuples*/
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+ IF (codingdata[1] < 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, 0,
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]);
+ }
+ ELSE IF (codingdata[1] == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+ ELSE IF (sub(codingdata[1], 1) == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]);
+ a1_msb = s_and(codingdata[2], 0x3);
+ tmp = L_and(xq[a1_i], 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (a1_msb == 0 && tmp > 0)
+ {
+ if (xq[a1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[a1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ IF (a1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ b1_msb = shr_pos(codingdata[2], 2);
+ tmp = L_and(xq[b1_i], 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (b1_msb == 0 && tmp > 0)
+ {
+ if (xq[b1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[b1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ IF (b1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+ ELSE
+ {
+ a1 = L_abs(xq[a1_i]);
+ b1 = L_abs(xq[b1_i]);
+ a1_msb = L_shr_pos(a1, 1);
+ tmp = L_and(a1, 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (a1_msb == 0 && tmp > 0)
+ {
+ if (xq[a1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[a1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ b1_msb = L_shr_pos(b1, 1);
+ tmp = s_and(b1, 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (b1_msb == 0 && tmp > 0)
+ {
+ if (xq[b1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[b1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]);
+ FOR (lev = 1; lev < codingdata[1]; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]);
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1));
+ }
+ lev1 = s_min(codingdata[1], 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]);
+ IF (a1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31));
+ }
+ IF (b1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31));
+ }
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /*end of the 2-tuples loop*/
+ }
+
+ /* Side bits (in sync with the decoder) */
+ nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6)));
+
+ /* Residual bits (in sync with the decoder) */
+ extra_bits = sub(norm_ul(st.ac_range_fx), 6);
+ if (st.ac_cache_fx >= 0)
+ {
+ extra_bits = add(extra_bits, 8);
+ }
+ if (st.ac_carry_count_fx > 0)
+ {
+ extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3));
+ }
+
+ n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0);
+ move16();
+
+ IF (lsbMode == 0)
+ {
+ numResBitsEnc = s_min(numResBits, n);
+ FOR (i = 0; i < numResBitsEnc; i++)
+ {
+ resbit = 0; move16();
+ i1 = shr(i, RESBITS_PACK_SHIFT);
+ i2 = s_and(i, RESBITS_PACK_MASK);
+ if (s_and(resBits[i1], shl(1, i2)))
+ {
+ resbit = 1;
+ }
+ write_bit_backward(ptr, &bp_side, &mask_side, resbit);
+ }
+ }
+ ELSE
+ {
+ nlsbs = s_min(nlsbs, n);
+ FOR (k = 0; k < nlsbs; k++)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]);
+ }
+ }
+
+ /* End arithmetic coder, overflow management */
+ extra_bits = ac_enc_finish_fx(ptr, &bp, &st);
+
+ /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/
+ fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc);
+
+ Dyn_Mem_Deluxe_Out();
+
+ return fill_bits;
+}
+
+# else /* ENABLE_HR_MODE */
+
+Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word16 xq[],
+ Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz,
+ Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode,
+ Word16 enable_lpc_weighting, Word8 *scratchBuffer)
+{
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits;
+ Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp;
+ Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev;
+ );
+#else
+ Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits;
+ Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp;
+ Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev;
+ );
+#endif
+
+
+ lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN * 2 bytes */
+
+ /* Init */
+ a1_i = 0;
+ move16();
+ b1_i = 1;
+ move16();
+ bp = 0;
+ move16();
+ numResBitsEnc = 0;
+ move16();
+ nlsbs = 0;
+ move16();
+ ptr = bytes;
+ bp_side = bp_side_in;
+ move16();
+ mask_side = mask_side_in;
+ move16();
+
+ /*Start Encoding*/
+ ac_enc_init_fx(&st);
+
+ /* TNS data */
+ FOR (n = 0; n < tns_numfilters; n++)
+ {
+ IF (tns_order[n] > 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1],
+ ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]);
+ FOR (k = 0; k < tns_order[n]; k++)
+ {
+ ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]],
+ ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]);
+ }
+ }
+ }
+
+ IF (lsbMode == 0)
+ {
+
+ /*Main Loop through the 2-tuples*/
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+ IF (codingdata[1] < 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]);
+ }
+ ELSE IF (codingdata[1] == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+ ELSE IF (sub(codingdata[1], 1) == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]);
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[a1_i], 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[b1_i], 1));
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+ ELSE
+ {
+ a1 = abs_s(xq[a1_i]);
+ b1 = abs_s(xq[b1_i]);
+ FOR (lev = 0; lev < codingdata[1]; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]);
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1));
+ }
+ lev1 = s_min(codingdata[1], 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /*end of the 2-tuples loop*/
+ }
+ ELSE
+ {
+ /*Main Loop through the 2-tuples*/
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+ IF (codingdata[1] < 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]);
+ }
+ ELSE IF (codingdata[1] == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]);
+ IF (xq[a1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ IF (xq[b1_i] != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+ ELSE IF (sub(codingdata[1], 1) == 0)
+ {
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]);
+ a1_msb = s_and(codingdata[2], 0x3);
+ tmp = s_and(xq[a1_i], 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (a1_msb == 0 && tmp > 0)
+ {
+ if (xq[a1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[a1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ IF (a1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ b1_msb = shr_pos(codingdata[2], 2);
+ tmp = s_and(xq[b1_i], 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (b1_msb == 0 && tmp > 0)
+ {
+ if (xq[b1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[b1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ IF (b1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+ ELSE
+ {
+ a1 = abs_s(xq[a1_i]);
+ b1 = abs_s(xq[b1_i]);
+ a1_msb = shr_pos(a1, 1);
+ tmp = s_and(a1, 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (a1_msb == 0 && tmp > 0)
+ {
+ if (xq[a1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[a1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ b1_msb = shr_pos(b1, 1);
+ tmp = s_and(b1, 1);
+ lsb[nlsbs++] = tmp;
+ move16();
+ test();
+ IF (b1_msb == 0 && tmp > 0)
+ {
+ if (xq[b1_i] > 0)
+ {
+ lsb[nlsbs++] = 0;
+ move16();
+ }
+ if (xq[b1_i] < 0)
+ {
+ lsb[nlsbs++] = 1;
+ move16();
+ }
+ }
+ ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]);
+ FOR (lev = 1; lev < codingdata[1]; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]);
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1));
+ write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1));
+ }
+ lev1 = s_min(codingdata[1], 3);
+ ac_encode_fx(ptr, &bp, &st,
+ ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]],
+ ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]);
+ IF (a1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15));
+ }
+ IF (b1_msb != 0)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15));
+ }
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /*end of the 2-tuples loop*/
+ }
+
+ /* Side bits (in sync with the decoder) */
+ nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6)));
+
+ /* Residual bits (in sync with the decoder) */
+ extra_bits = sub(norm_ul(st.ac_range_fx), 6);
+ if (st.ac_cache_fx >= 0)
+ {
+ extra_bits = add(extra_bits, 8);
+ }
+ if (st.ac_carry_count_fx > 0)
+ {
+ extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3));
+ }
+
+ n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0);
+ move16();
+
+ IF (lsbMode == 0)
+ {
+ numResBitsEnc = s_min(numResBits, n);
+ FOR (i = 0; i < numResBitsEnc; i++)
+ {
+ FOR (i = 0; i < numResBitsEnc; i++)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, resBits[i]);
+ }
+ }
+ }
+ ELSE
+ {
+ nlsbs = s_min(nlsbs, n);
+ FOR (k = 0; k < nlsbs; k++)
+ {
+ write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]);
+ }
+ }
+
+ /* End arithmetic coder, overflow management */
+ extra_bits = ac_enc_finish_fx(ptr, &bp, &st);
+
+ /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/
+ fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc);
+
+ Dyn_Mem_Deluxe_Out();
+ return fill_bits;
+}
+
+#endif /* ENABLE_HR_MODE */
+
+void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec,
+ Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode,
+ Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx,
+ Word16 frame_dms,
+ Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx,
+ Word16 *b_left,
+ Word16 *resBits,
+# ifdef ENABLE_HR_MODE
+ Word32 *x,
+# else
+ Word16 *x,
+# endif
+ Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer
+# ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+# endif
+)
+{
+ Decoder_State_fx st;
+# ifdef ENABLE_HR_MODE
+ Word16 resbit, i1, i2;
+ Word32 a, b;
+# else
+ Word16 a, b;
+# endif
+ Word16 t, a1, b1, a1_i, b1_i, bp;
+ Word16 esc_nb;
+ Word16 rateFlag;
+ Word16 r;
+ Word16 nt_half;
+ Word16 c;
+ Word16 nbits_side, extra_bits, nbits_ari;
+ UWord8 * ptr;
+ Word32 tmp32;
+ Word16 lsb_ind_c;
+ Word16 * lsb_ind;
+ Word16 tmp;
+ Counter n, k, lev;
+ Counter i;
+ Word16 max_lev = 14;
+
+#ifdef DYNMEM_COUNT
+struct _dynmem
+{
+Decoder_State_fx st;
+ Pc_State_fx pc;
+ Word16 resbit, i1, i2;
+# ifdef ENABLE_HR_MODE
+ Word32 a, b;
+# else
+ Word16 a, b;
+# endif
+ Word16 t, a1, b1, a1_i, b1_i, bp;
+ Word16 esc_nb;
+ Word16 rateFlag;
+ Word16 r;
+ Word16 nt_half;
+ Word16 c;
+ Word16 nbits_side, extra_bits, nbits_ari;
+ UWord8 * ptr;
+ Word32 tmp32;
+ Word16 lsb_ind_c;
+ Word16 * lsb_ind;
+ Word16 tmp;
+ Counter i, n, k, lev;
+ };
+ Dyn_Mem_In("processAriDecoder_fx", sizeof(struct _dynmem));
+#endif
+
+# ifdef ENABLE_HR_MODE
+ if (hrmode == 1)
+ {
+ max_lev = max_lev + 8;
+ }
+# endif
+
+ lsb_ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size 2 * MAX_LEN bytes */
+
+ /* Rate flag */
+ rateFlag = 0;
+ move16();
+# ifdef ENABLE_HR_MODE
+ if (fs_idx != 5) /* Don't update rateFlag for 96000 Hz */
+# endif
+ {
+ if (sub(nbbits, add(160, DEPR_i_mult(fs_idx, 160))) > 0)
+ {
+ rateFlag = 2 << NBITS_CONTEXT;
+ move16();
+ }
+ }
+
+ pc_init_fx(n_pc, shr_pos(nbbits, 3), be_bp_left, be_bp_right, L_spec, mode==1, mode==2, *bfi, &st.pc);
+
+ /* Init */
+ nt_half = shr_pos(L_spec, 1);
+ c = 0;
+ move16();
+ t = 0;
+ move16();
+ a1_i = 0;
+ move16();
+ b1_i = 1;
+ move16();
+ bp = 0;
+ move16();
+ if (mode != 1)
+ {
+ bp = add(bp, st.pc.bytes);
+ move16();
+ }
+ *spec_inv_idx = L_spec;
+ move16();
+ *b_left = -1;
+ move16();
+ lsb_ind_c = 0;
+ move16();
+
+ptr = bytes;
+
+/* Start Decoding */
+ac_dec_init_fx(ptr, &bp, bp_side, mask_side, &st);
+
+ /* Decode TNS data */
+ tmp = MAXLAG;
+IF (sub(frame_dms, 25) == 0)
+{
+tmp = shr_pos(tmp, 1);
+}
+IF (sub(frame_dms, 50) == 0)
+{
+tmp = shr_pos(tmp, 1);
+}
+
+ FOR (n = 0; n < tns_numfilters; n++)
+ {
+ IF (tns_order[n] > 0)
+ {
+ tns_order[n] = ac_decode_tns_order(&st, enable_lpc_weighting);
+ move16();
+ tns_order[n] = add(tns_order[n], 1);
+ move16();
+ IF (tns_order[n] > tmp)
+ {
+ GOTO ber_detect;
+ }
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st,
+ ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1],
+ ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ FOR (k = 0; k < tns_order[n]; k++)
+ {
+ IF (sub(*bp_side, bp) < 0)
+ {
+ GOTO ber_detect;
+ }
+ tns_idx[MAXLAG * n + k] = ac_decode_tns_coef(&st, k);
+ move16();
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st,
+ ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]],
+ ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ }
+ }
+ }
+ IF (st.BER_detect > 0)
+ {
+ GOTO ber_detect;
+ }
+
+IF (lsbMode == 0)
+{
+
+/*Main Loop through the 2-tuples*/
+FOR (k = 0; k < lastnz; k += 2)
+{
+
+/* Get context */
+t = add(c, rateFlag);
+if (sub(k, nt_half) > 0)
+{
+t = add(t, 1 << NBITS_CONTEXT);
+}
+
+ r = ac_decode_fx(&st, ari_spec_lookup[t]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r],
+ ari_spec_freq[ari_spec_lookup[t]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+
+ IF (r == 0)
+ {
+ x[a1_i] = 0;
+ move16();
+ x[b1_i] = 0;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (sub(r, VAL_ESC) < 0)
+ {
+ a = s_and(r, 0x3);
+ b = shr_pos(r, 2);
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1));
+ IF (a > 0)
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ a = negate(a);
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ b = negate(b);
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ }
+ ELSE
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+GOTO ber_detect;
+}
+a = read_bit(ptr, bp_side, mask_side);
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+GOTO ber_detect;
+}
+ b = read_bit(ptr, bp_side, mask_side);
+ r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st,
+ ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r],
+ ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ IF (sub(r, VAL_ESC) < 0)
+ {
+ a1 = s_and(r, 0x3);
+ b1 = shr_pos(r, 2);
+ a = add(shl_pos(a1, 1), a);
+ b = add(shl_pos(b1, 1), b);
+ IF (a > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ a = negate(a);
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ b = negate(b);
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1));
+ }
+ ELSE
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+a = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), a);
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ b = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), b);
+ FOR (lev = 2; lev < max_lev; lev++)
+ {
+ esc_nb = s_min(lev, 3);
+ r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st,
+ ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r],
+ ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ IF (sub(r, VAL_ESC) < 0)
+ {
+ BREAK;
+ }
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+
+# ifdef ENABLE_HR_MODE
+ a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a);
+# else
+ a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a);
+# endif
+
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+# ifdef ENABLE_HR_MODE
+ b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b);
+# else
+ b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b);
+# endif
+ }
+ /* check for bitflip */
+ IF (sub(lev, max_lev) == 0)
+ {
+ GOTO ber_detect;
+ }
+
+ b1 = shr_pos(r, 2);
+ a1 = s_and(r, 0x3);
+
+# ifdef ENABLE_HR_MODE
+ a = L_add(L_shl(a1, lev), a);
+ b = L_add(L_shl(b1, lev), b);
+# else
+ a = add(shl(a1, lev), a);
+ b = add(shl(b1, lev), b);
+# endif
+ IF (a > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+# ifdef ENABLE_HR_MODE
+ a = L_negate(a);
+# else
+ a = negate(a);
+# endif
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+# ifdef ENABLE_HR_MODE
+ b = L_negate(b);
+# else
+ b = negate(b);
+# endif
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12));
+ }
+ }
+
+ test();
+ test();
+ IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0)
+{
+GOTO ber_detect;
+}
+
+a1_i += 2;
+b1_i += 2;
+}
+}
+ELSE
+{
+/*Main Loop through the 2-tuples*/
+FOR (k = 0; k < lastnz; k += 2)
+{
+
+/* Get context */
+t = add(c, rateFlag);
+if (sub(k, nt_half) > 0)
+{
+t = add(t, 1 << NBITS_CONTEXT);
+}
+
+ r = ac_decode_fx(&st, ari_spec_lookup[t]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r],
+ ari_spec_freq[ari_spec_lookup[t]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+
+ IF (r == 0)
+ {
+ x[a1_i] = 0;
+ move16();
+ x[b1_i] = 0;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (sub(r, VAL_ESC) < 0)
+ {
+ a = s_and(r, 0x3);
+ b = shr_pos(r, 2);
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1));
+ IF (a > 0)
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ a = negate(a);
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ b = negate(b);
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ }
+ ELSE
+ {
+ r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st,
+ ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r],
+ ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ IF (sub(r, VAL_ESC) < 0)
+ {
+ a1 = s_and(r, 0x3);
+ b1 = shr_pos(r, 2);
+ a = shl_pos(a1, 1);
+ b = shl_pos(b1, 1);
+ IF (a > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ a = negate(a);
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ b = negate(b);
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1));
+ lsb_ind[lsb_ind_c++] = k;
+ move16();
+ }
+ ELSE
+ {
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+a = shl_pos(read_bit(ptr, bp_side, mask_side), 1);
+if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+{
+ GOTO ber_detect;
+}
+ b = shl_pos(read_bit(ptr, bp_side, mask_side), 1);
+ FOR (lev = 2; lev < max_lev; lev++)
+ {
+ esc_nb = s_min(lev, 3);
+ r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]);
+ if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st,
+ ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r],
+ ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0)
+ {
+ GOTO ber_detect;
+ }
+ IF (sub(r, VAL_ESC) < 0)
+ {
+ BREAK;
+ }
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+# ifdef ENABLE_HR_MODE
+ a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a);
+# else
+ a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a);
+# endif
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+# ifdef ENABLE_HR_MODE
+ b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b);
+# else
+ b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b);
+# endif
+ }
+ /* check for bitflip */
+ IF (sub(lev, max_lev) == 0)
+ {
+ GOTO ber_detect;
+ }
+
+ b1 = shr_pos(r, 2);
+ a1 = s_and(r, 0x3);
+# ifdef ENABLE_HR_MODE
+ a = L_add(L_shl(a1, lev), a);
+ b = L_add(L_shl(b1, lev), b);
+# else
+ a = add(shl(a1, lev), a);
+ b = add(shl(b1, lev), b);
+# endif
+ IF (a > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+# ifdef ENABLE_HR_MODE
+ a = L_negate(a);
+# else
+ a = negate(a);
+# endif
+ }
+ }
+ x[a1_i] = a;
+ move16();
+ IF (b > 0)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect;
+ }
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+# ifdef ENABLE_HR_MODE
+ b = L_negate(b);
+# else
+ b = negate(b);
+# endif
+ }
+ }
+ x[b1_i] = b;
+ move16();
+ c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12));
+ lsb_ind[lsb_ind_c++] = k;
+ move16();
+ }
+ }
+
+ test();
+ test();
+ IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0)
+{
+GOTO ber_detect;
+}
+
+a1_i += 2;
+b1_i += 2;
+}
+}
+
+IF (L_spec > k)
+{
+basop_memset(&x[k], 0, (L_spec - k) * sizeof(*x));
+}
+
+ nbits_side = sub(nbbits, add(shl_pos(*bp_side, 3), sub(norm_s(*mask_side), 6)));
+ extra_bits = sub(norm_ul(st.ac_range_fx), 6);
+ nbits_ari = shl_pos(sub(bp, 3), 3);
+IF (mode != 1)
+{
+IF (st.pc.c_bp == 0)
+{
+nbits_ari = shl_pos(sub(sub(bp, st.pc.bytes), 3), 3);
+}
+ELSE
+{
+nbits_ari = shl_pos(add(bp, sub(sub(st.pc.b_left, st.pc.bytes), 3)), 3);
+}
+
+ IF (st.pc.c_bp_side != 0)
+ {
+ nbits_side = sub(add(sub(nbbits, shl_pos(st.pc.b_left, 3)), shl_pos(sub(st.pc.bytes, *bp_side), 3)),
+ sub(norm_s(*mask_side), 6));
+ }
+ }
+
+ n = sub(nbbits, add(nbits_ari, add(extra_bits, nbits_side)));
+ move16();
+
+IF (n < 0)
+{
+GOTO ber_detect;
+}
+
+ IF (lsbMode == 0)
+ {
+ *resBits = n;
+ move16();
+ i=0;
+
+#ifdef ENABLE_HR_MODE
+ FOR (k = 0; k < L_spec; k++)
+ {
+ IF (x[k] != 0)
+ {
+ IF (n == 0)
+ {
+ BREAK;
+ }
+ if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect_res;
+ }
+ i1 = shr(i, RESBITS_PACK_SHIFT);
+ i2 = s_and(i, RESBITS_PACK_MASK);
+ resbit = read_bit(ptr, bp_side, mask_side);
+ if (resbit)
+ {
+ resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2));
+ }
+ i = add(i, 1);
+ move16();
+ n = sub(n, 1);
+ }
+ }
+#else
+ FOR (k = 0; k < L_spec; k++)
+ {
+ IF (x[k] != 0)
+ {
+ IF (n == 0)
+ {
+ BREAK;
+ }
+
+ if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect_res;
+ }
+
+ *resQdata++ = (UWord8) read_bit(ptr, bp_side, mask_side);
+ move16();
+ n = sub(n, 1);
+ }
+ }
+#endif
+
+# ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ Word16 idx_len = sub(*resBits, n); /* Number of nonzero bits */
+ Word16 idx_len_lim = idx_len * EXT_RES_ITER_MAX;
+
+ Word16 res_bits_hrmode = s_min(idx_len_lim, *resBits) - idx_len;
+ /* idx_len bits have been read in the previous loop */
+
+ for (k = 0; k < res_bits_hrmode; k++)
+ {
+ if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+ {
+ GOTO ber_detect_res;
+ }
+ i1 = shr(i, RESBITS_PACK_SHIFT);
+ i2 = s_and(i, RESBITS_PACK_MASK);
+ resbit = read_bit(ptr, bp_side, mask_side);
+ if (resbit)
+ {
+ resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2));
+ }
+ i = add(i, 1);
+ move16();
+ n = sub(n, 1);
+ }
+ }
+# endif
+
+ *resBits = sub(*resBits, n);
+ }
+ ELSE
+ {
+ *resBits = 0;
+ FOR (k = 0; k < lsb_ind_c; k++)
+ {
+ a = x[lsb_ind[k]];
+ move16();
+ IF (n == 0)
+ {
+ BREAK;
+ }
+if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+{
+GOTO ber_detect_res;
+}
+ tmp = read_bit(ptr, bp_side, mask_side);
+ n = sub(n, 1);
+ IF (tmp > 0)
+ {
+# ifdef ENABLE_HR_MODE
+ if (a > 0)
+ {
+ a = L_add(a, 1);
+ }
+ if (a < 0)
+ {
+ a = L_sub(a, 1);
+ }
+# else
+ if (a > 0)
+ {
+ a = add(a, 1);
+ }
+ if (a < 0)
+ {
+ a = sub(a, 1);
+ }
+# endif
+ IF (a == 0)
+ {
+ IF (n == 0)
+ {
+ BREAK;
+ }
+ a = 1;
+if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+{
+ GOTO ber_detect_res;
+}
+if (read_bit(ptr, bp_side, mask_side) != 0)
+{
+ a = negate(a);
+}
+n = sub(n, 1);
+}
+}
+
+ x[lsb_ind[k]] = a;
+ move16();
+ b = x[lsb_ind[k] + 1];
+ move16();
+ IF (n == 0)
+ {
+ BREAK;
+ }
+if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+{
+GOTO ber_detect_res;
+}
+ tmp = read_bit(ptr, bp_side, mask_side);
+ n = sub(n, 1);
+ IF (tmp > 0)
+ {
+# ifdef ENABLE_HR_MODE
+ if (b > 0)
+ {
+ b = L_add(b, 1);
+ }
+ if (b < 0)
+ {
+ b = L_sub(b, 1);
+ }
+# else
+ if (b > 0)
+ {
+ b = add(b, 1);
+ }
+ if (b < 0)
+ {
+ b = sub(b, 1);
+ }
+# endif
+ IF (b == 0)
+ {
+ IF (n == 0)
+ {
+ BREAK;
+ }
+ b = 1;
+if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0)
+{
+ GOTO ber_detect_res;
+}
+ if (read_bit(ptr, bp_side, mask_side) != 0)
+ {
+ b = negate(b);
+ }
+ n = sub(n, 1);
+ }
+ }
+ x[lsb_ind[k] + 1] = b;
+ move16();
+ }
+ }
+
+/* Noise Filling seed */
+ tmp32 = L_deposit_l(0);
+ FOR (i = 0; i < L_spec; i++)
+ {
+# ifdef ENABLE_HR_MODE
+ tmp32 = L_mac0(tmp32, L_and(L_abs(x[i]), 32767), i);
+# else
+ tmp32 = L_mac0(tmp32, abs_s(x[i]), i);
+# endif
+ }
+ *nf_seed = extract_l(tmp32);
+ move16();
+
+ /* Detect zero frame */
+ test();
+ test();
+ test();
+ test();
+ IF (sub(lastnz, 2) == 0 && sub(x[0], 0) == 0 && sub(x[1], 0) == 0 && sub(gg_idx, 0) == 0 && sub(fac_ns_idx, 7) == 0)
+ {
+ *zero_frame = 1;
+ move16();
+ }
+ ELSE
+ {
+ *zero_frame = 0;
+ move16();
+ }
+
+IF (mode == 1)
+ {
+ IF (st.pc.bytes > 0)
+ {
+ IF (sub(st.pc.b_left, shr_pos(nbbits, 3)) > 0)
+ {
+ *b_left = sub(*bp_side, st.pc.bytes);
+ }
+ }
+ }
+IF (mode == 2)
+{
+IF (st.pc.bytes > 0)
+{
+IF (sub(st.pc.b_left, shr_pos(nbbits,3)) > 0)
+{
+*b_left = *bp_side;
+}
+}
+}
+
+IF (sub(*bfi, 2) == 0)
+{
+IF (sub(*spec_inv_idx, L_spec) == 0)
+{
+*bfi = 0;
+}
+}
+GOTO bail;
+
+/* goto for bit error handling */
+ber_detect:
+ *bfi = 1;
+ move16();
+ *b_left = st.pc.b_left;
+ move16();
+ test();
+ IF (st.pc.inv_bin > 0 && sub(st.pc.inv_bin, L_spec) <= 0)
+ {
+ *spec_inv_idx = st.pc.inv_bin;
+ move16();
+ *bfi = 2;
+ move16();
+ *resBits = 0;
+ move16();
+ *zero_frame = 0;
+ move16();
+ /* Noise Filling seed */
+ tmp32 = L_deposit_l(0);
+ FOR (i = 0; i < *spec_inv_idx; i++)
+ {
+ tmp32 = L_mac0(tmp32, abs_s(x[i]), i);
+ }
+ *nf_seed = extract_l(tmp32);
+ move16();
+ }
+GOTO bail;
+
+/* goto for bit error handling in residual signal */
+ber_detect_res:
+ *b_left = st.pc.b_left;
+ move16();
+ *resBits = 0;
+ move16();
+ *bfi = 0;
+ move16();
+ *zero_frame = 0;
+ move16();
+ /* Noise Filling seed */
+ tmp32 = L_deposit_l(0);
+ FOR (i = 0; i < *spec_inv_idx; i++)
+ {
+ tmp32 = L_mac0(tmp32, abs_s(x[i]), i);
+ }
+ *nf_seed = extract_l(tmp32);
+ move16();
+ GOTO bail;
+
+/* goto, because of dynmem out */
+bail:
+Dyn_Mem_Deluxe_Out();
+}
+
+
+void processAriDecoderScaling_fx(
+# ifdef ENABLE_HR_MODE
+ Word32 *datain,
+# else
+ Word16 *data16,
+# endif
+ Word16 dataLen, Word32 *data32, Word16 *data_e)
+{
+ Counter i;
+
+# ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(Word16 shift; Word32 tmp, x_min, x_max;);
+# else
+ Dyn_Mem_Deluxe_In(Word16 shift; Word16 tmp, x_min, x_max;);
+# endif
+
+
+#ifdef ENABLE_HR_MODE
+ x_max = 0;
+ move32();
+ x_min = 0;
+ move32();
+#else
+ x_max = 0;
+ move16();
+ x_min = 0;
+ move16();
+#endif
+
+ FOR (i = 0; i < dataLen; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ if (datain[i] > 0)
+ x_max = L_max(x_max, datain[i]);
+ if (datain[i] < 0)
+ x_min = L_min(x_min, datain[i]);
+#else
+ if (data16[i] > 0)
+ x_max = s_max(x_max, data16[i]);
+ if (data16[i] < 0)
+ x_min = s_min(x_min, data16[i]);
+#endif
+ }
+
+#ifdef ENABLE_HR_MODE
+ tmp = L_max(x_max, L_negate(x_min));
+ shift = norm_l(tmp);
+ if (tmp == 0)
+ {
+ shift = 31;
+ move32();
+ }
+#else
+ tmp = s_max(x_max, negate(x_min));
+ shift = norm_s(tmp);
+ if (tmp == 0)
+ {
+ shift = 15;
+ move16();
+ }
+#endif
+
+ FOR (i = 0; i < dataLen; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ data32[i] = L_shl_pos(datain[i], shift);
+#else
+ data32[i] = L_shl_pos(L_deposit_h(data16[i]), shift);
+#endif
+ }
+
+#ifdef ENABLE_HR_MODE
+ *data_e = sub(31, shift);
+ move16();
+#else
+ *data_e = sub(15, shift);
+ move16();
+#endif
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+/*************************************************************************/
+
+static __forceinline UWord32 UL_addNs24(UWord32 UL_var1, UWord32 UL_var2, UWord16 *wrap)
+{
+ return UL_lshr(UL_addNs(UL_lshl(UL_var1, 8), UL_lshl(UL_var2, 8), wrap), 8);
+}
+#ifdef ENABLE_HR_MODE
+Word16 find_last_nz_pair(const Word32 x[], Word16 length)
+#else
+Word16 find_last_nz_pair(const Word16 x[], Word16 length)
+#endif
+{
+ Dyn_Mem_Deluxe_In(Word16 last_nz, lobs[4]; Counter stage, i;);
+
+ lobs[0] = 4;
+ move16();
+ lobs[1] = shr_pos(length, 1); /* length/2 */
+ move16();
+ lobs[2] = add(lobs[1], shr_pos(length, 2));
+ move16();
+ lobs[3] = add(lobs[2], shr_pos(length, 3));
+ move16();
+
+ last_nz = 0;
+ move16();
+ i = length;
+ move16();
+ FOR (stage = 3; stage >= 0; --stage)
+ {
+ /* unmapped kernel */
+ FOR (; i >= lobs[stage]; i -= 2)
+ {
+ if (x[i - 2] != 0)
+ {
+ last_nz = s_max(last_nz, i);
+ }
+ if (x[i - 1] != 0)
+ {
+ last_nz = s_max(last_nz, i);
+ }
+ }
+ IF (last_nz > 0)
+ {
+ BREAK;
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return s_max(last_nz, 2);
+}
+
+
+void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit)
+{
+ if (bit > 0)
+ {
+ ptr[*bp] = (UWord8)s_or((Word16)ptr[*bp], *mask);
+ move16();
+ }
+ *mask = lshl_pos(*mask, 1);
+ move16();
+ if (sub(*mask, 0x100) == 0)
+ {
+ *mask = 1;
+ move16();
+ }
+ if (sub(*mask, 1) == 0)
+ {
+ *bp = sub(*bp, 1);
+ move16();
+ }
+}
+
+
+void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits)
+{
+ Dyn_Mem_Deluxe_In(Counter k; Word16 bit;);
+
+ FOR (k = 0; k < numbits; k++)
+ {
+ bit = s_and(indice, 1);
+ write_bit_backward(ptr, bp, mask, bit);
+ indice = lshr(indice, 1);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+static __forceinline void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits)
+{
+ Dyn_Mem_Deluxe_In(Counter k; Word16 bit, mask, tmp;);
+
+ tmp = (Word16)ptr[bp];
+ move16();
+ mask = 0x80;
+ move16();
+ FOR (k = 0; k < numbits; k++)
+ {
+ bit = s_and(indice, mask);
+ tmp = s_or(tmp, mask);
+ if (bit == 0)
+ {
+ tmp = sub(tmp, mask);
+ }
+ mask = lshr(mask, 1);
+ }
+ ptr[bp] = (UWord8)tmp;
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+static __forceinline void ac_enc_init_fx(Encoder_State_fx *st_fx) /* i/o: Encoder state */
+{
+ st_fx->ac_low_fx = L_deposit_l(0);
+ move32();
+ st_fx->ac_range_fx = 0x00ffffff;
+ move32();
+ st_fx->ac_cache_fx = -1;
+ move16();
+ st_fx->ac_carry_fx = 0;
+ move16();
+ st_fx->ac_carry_count_fx = 0;
+ move16();
+}
+
+static __forceinline void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */
+{
+ test();
+ L_sub(0, 0); /* For comparision in if */
+ IF (st_fx->ac_low_fx < (0x00ff0000UL) || sub(st_fx->ac_carry_fx, 1) == 0)
+ {
+ IF (st_fx->ac_cache_fx >= 0)
+ {
+ ptr[(*bp)++] = (UWord8)add(st_fx->ac_cache_fx, st_fx->ac_carry_fx);
+ move16();
+ }
+
+ WHILE (st_fx->ac_carry_count_fx > 0)
+ {
+ ptr[(*bp)++] = (UWord8)s_and(add(st_fx->ac_carry_fx, 0xff), 255);
+ move16();
+ st_fx->ac_carry_count_fx = sub(st_fx->ac_carry_count_fx, 1);
+ move16();
+ }
+
+ st_fx->ac_cache_fx = u_extract_l(UL_lshr_pos(st_fx->ac_low_fx, 16));
+ move16();
+ st_fx->ac_carry_fx = 0;
+ move16();
+ }
+ ELSE
+ {
+ st_fx->ac_carry_count_fx = add(st_fx->ac_carry_count_fx, 1);
+ move16();
+ }
+ st_fx->ac_low_fx = UL_and(UL_lshl_pos(st_fx->ac_low_fx, 8), 0x00ffffff);
+ move32();
+}
+
+static __forceinline void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */
+ UWord32 cum_freq, /* i : Cumulative frequency up to symbol */
+ UWord32 sym_freq) /* i : Symbol probability */
+{
+ Dyn_Mem_Deluxe_In(UWord32 r, tmp; UWord16 carry;);
+
+ r = UL_lshr_pos(st_fx->ac_range_fx, 10);
+ tmp = UL_Mpy_32_32(r, cum_freq);
+
+ assert(r < (1U << 24));
+ assert(cum_freq < (1U << 24));
+ assert(tmp < (1U << 24));
+ assert(st_fx->ac_low_fx < (1U << 24));
+ st_fx->ac_low_fx = UL_addNs24(st_fx->ac_low_fx, tmp, &carry);
+ move32();
+
+ if (carry != 0)
+ {
+ st_fx->ac_carry_fx = carry;
+ move16();
+ }
+
+ st_fx->ac_range_fx = UL_Mpy_32_32(r, sym_freq);
+ move32();
+
+ assert(cum_freq < (1U << 24));
+ assert(st_fx->ac_range_fx < (1U << 24));
+ WHILE (st_fx->ac_range_fx < (1U << 16))
+ {
+ L_sub(0, 0); /* Comparison in while */
+ st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8);
+ move32();
+
+ assert(st_fx->ac_range_fx < (1U << 24));
+
+ ac_enc_shift_fx(ptr, bp, st_fx);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+static __forceinline Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */
+{
+ Dyn_Mem_Deluxe_In(UWord32 val, mask, high; Word16 bits; UWord16 over1, over2;);
+
+ /*bits = 24 - log2_i(st->ac_range); */
+ bits = sub(norm_ul(st_fx->ac_range_fx), 7);
+
+ mask = UL_lshr(0x00ffffff, bits);
+
+ val = UL_addNs24(st_fx->ac_low_fx, mask, &over1);
+ high = UL_addNs24(st_fx->ac_low_fx, st_fx->ac_range_fx, &over2);
+
+ L_xor(0, 0); /* For bit not */
+ UL_and(1U, 1U); /* added counters */
+ val = L_and(val, (~mask) & 0x00ffffff);
+
+ L_xor(0, 0); /* For bit not */
+ IF ((L_xor(over1, over2)) == 0)
+ {
+ L_sub(0, 0); /* For comparision in if */
+ IF (UL_addNsD(val, mask) >= high)
+ {
+ bits = add(bits, 1);
+ mask = UL_lshr_pos(mask, 1);
+ val = UL_and(UL_addNsD(st_fx->ac_low_fx, mask), (~mask) & 0x00ffffff);
+ L_xor(0, 0);
+ UL_and(1, 1); /* For bit not , mask */
+ }
+
+ if (val < st_fx->ac_low_fx)
+ {
+ st_fx->ac_carry_fx = 1;
+ move16();
+ }
+ }
+
+ st_fx->ac_low_fx = val;
+ move32();
+
+ FOR (; bits > 0; bits -= 8)
+ {
+ ac_enc_shift_fx(ptr, bp, st_fx);
+ }
+ bits = add(bits, 8);
+
+ assert(st_fx->ac_carry_fx == 0);
+
+ IF (st_fx->ac_carry_count_fx > 0)
+ {
+ ptr[(*bp)++] = (UWord8)st_fx->ac_cache_fx;
+ move16();
+
+ FOR (; st_fx->ac_carry_count_fx > 1; st_fx->ac_carry_count_fx--)
+ {
+ ptr[(*bp)++] = 0xff;
+ move16();
+ }
+ write_indice_forward(ptr, *bp, lshr(0xff, sub(8, bits)), bits);
+ }
+ ELSE
+ {
+ write_indice_forward(ptr, *bp, st_fx->ac_cache_fx, bits);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return bits;
+}
+
+
+__forceinline Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask)
+{
+ Dyn_Mem_Deluxe_In(Word16 bit;);
+
+ bit = 0;
+ move16();
+ if (s_and((Word16)ptr[*bp], *mask) > 0)
+ {
+ bit = 1;
+ move16();
+ }
+ *mask = lshl_pos(*mask, 1);
+ move16();
+ if (sub(*mask, 0x100) == 0)
+ {
+ *mask = 1;
+ move16();
+ }
+ if (sub(*mask, 1) == 0)
+ {
+ *bp = sub(*bp, 1);
+ move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return bit;
+}
+
+
+static __forceinline void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side,
+ Decoder_State_fx *st_fx) /* i/o: Decoder State */
+{
+ Dyn_Mem_Deluxe_In(Counter i;);
+
+
+ st_fx->ac_low_fx = L_deposit_l(0);
+ move32();
+
+ st_fx->ac_range_fx = 0x00ffffff;
+ move32();
+ FOR (i = 0; i < 3; i++)
+ {
+ if (check_pc_bytes(bp, bp_side, mask_side, 0, 1, &st_fx->pc) != 0)
+ {
+ Dyn_Mem_Deluxe_Out();
+ return;
+ }
+ st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++]));
+ move32();
+ assert(st_fx->ac_low_fx < (1U << 24));
+ }
+
+ st_fx->BER_detect = 0;
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/* o : Decoded cumulative frequency */
+static __forceinline Word16 ac_decode_fx(Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 pki)
+{
+ Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;);
+
+ st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10);
+ move32();
+ val = 0;
+ move16();
+
+ r = add(val, 8);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 4);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 2);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 1);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn);
+ IF (sgn == 0)
+ {
+ val = r;
+ move16();
+ IF (sub(val, 15) == 0)
+ {
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][16]), &sgn);
+ if (sgn == 0)
+ {
+ val = 16;
+ move16();
+ }
+ UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn);
+ if (sgn == 0)
+ {
+ st_fx->BER_detect = 1;
+ move16();
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return val;
+}
+
+/* o : Decoded cumulative frequency */
+static __forceinline Word16 ac_decode_tns_order(Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 enable_lpc_weighting)
+{
+ Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;);
+
+ st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10);
+ move32();
+ val = 0;
+ move16();
+
+ r = add(val, 4);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 2);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 1);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn);
+ if (sgn == 0)
+ {
+ st_fx->BER_detect = 1;
+ move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return val;
+}
+
+/* o : Decoded cumulative frequency */
+static __forceinline Word16 ac_decode_tns_coef(Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ Word16 pki)
+{
+ Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;);
+
+ st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10);
+ move32();
+ val = 0;
+ move16();
+
+ r = add(val, 8);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 4);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 2);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ }
+
+ r = add(val, 1);
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn);
+ if (sgn == 0)
+ {
+ val = r;
+ move16();
+ IF (sub(val, 15) == 0)
+ {
+ UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][16]), &sgn);
+ if (sgn == 0)
+ {
+ val = 16;
+ move16();
+ }
+ UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn);
+ if (sgn == 0)
+ {
+ st_fx->BER_detect = 1;
+ move16();
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return val;
+}
+
+static __forceinline Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side,
+ Word16 cur_bin, Decoder_State_fx *st_fx, /* i/o: Decoder State */
+ UWord32 cum_freq, /* i : Cumulative frequency */
+ UWord32 sym_freq /* i : Symbol frequency */
+)
+{
+ UWord32 UL_tmp;
+
+
+ assert(st_fx->ac_help_fx < (1U << 24));
+ assert(cum_freq < (1U << 24));
+
+ UL_tmp = UL_Mpy_32_32(cum_freq, st_fx->ac_help_fx);
+ assert(UL_tmp < (1U << 24));
+
+ st_fx->ac_low_fx = UL_subNsD(st_fx->ac_low_fx, UL_tmp);
+ move32(); /*0+0*/
+ assert(st_fx->ac_low_fx < (1U << 24));
+
+ st_fx->ac_range_fx = UL_Mpy_32_32(st_fx->ac_help_fx, sym_freq);
+ move32();
+
+ assert(st_fx->ac_range_fx < (1U << 24));
+ /* updated to 16 from 24 */
+ WHILE (st_fx->ac_range_fx < (1U << 16))
+ {
+ L_sub(0, 0); /* For comparision in while*/
+
+ st_fx->ac_low_fx =
+ UL_and(st_fx->ac_low_fx, 0x0000ffFF); /* make sure upshift doe not lead to more than 24 bits */
+ assert(st_fx->ac_low_fx < 1U << 16);
+
+ if (check_pc_bytes(bp, bp_side, mask_side, cur_bin, 1, &st_fx->pc) != 0)
+ return 1;
+
+ /*shift in 8 bits */
+ st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++]));
+ move32();
+
+ assert(st_fx->ac_low_fx < (1U << 24));
+ st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8);
+ move32();
+ assert(st_fx->ac_range_fx < (1U << 24));
+ }
+ return 0;
+}
+
+static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec,
+ Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */
+)
+{
+pc->inv_bin = add(L_spec, 1); move16();
+pc->numbytes = numbytes; move16();
+pc->c_bp = 0; move16();
+pc->c_bp_side = 0; move16();
+pc->bytes = shr(add(n_pc, 1),1); move16();
+pc->b_left = add(numbytes,1); move16();
+pc->b_right = -1; move16();
+pc->enc = enc; move16();
+pc->sim_dec = sim_dec; move16();
+pc->bfi = bfi; move16();
+pc->be_bp_left = shr(be_bp_left, 3); move16();
+pc->be_bp_right = shr(be_bp_right, 3); move16();
+ assert(pc->be_bp_right < pc->bytes || pc->bytes == 0);
+}
+
+static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin,
+ Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */)
+{
+ Dyn_Mem_Deluxe_In(Word16 bp_local, bp_side_local, offset;);
+
+ IF (pc->bytes > 0)
+ {
+ test();
+ IF (from_left == 0 && sub(*mask_side, 1) != 0)
+ {
+ Dyn_Mem_Deluxe_Out();
+ return 0;
+ }
+ test();
+ IF (pc->c_bp_side > 0 && *bp_side < 0)
+ {
+ assert(*mask_side == 1);
+ assert(pc->b_right != -1);
+ *bp_side = pc->b_right;
+ Dyn_Mem_Deluxe_Out();
+ return 0;
+ }
+ bp_local = *bp;
+ bp_side_local = *bp_side;
+
+ IF (from_left != 0)
+ {
+ if (sub(*mask_side, 1) == 0)
+ {
+ bp_side_local = add(bp_side_local, 1);
+ }
+ }
+ ELSE
+ {
+ bp_local = sub(bp_local, 1);
+ }
+
+ IF (pc->b_right < 0)
+ {
+ offset = -1;
+ move16();
+ if (pc->enc == 0)
+ {
+ offset = add(offset, pc->bytes);
+ }
+
+ IF (add(bp_side_local, sub(offset, bp_local)) == pc->bytes)
+ {
+ pc->b_left = add(bp_local, 1);
+ pc->b_right = sub(bp_side_local, 1);
+ IF (pc->enc != 0)
+ {
+ assert(pc->b_right - pc->b_left + 1 == pc->bytes);
+ Dyn_Mem_Deluxe_Out();
+ return 1;
+ }
+ }
+ }
+
+ test();
+ IF (pc->enc == 0 && pc->b_right >= 0)
+ {
+ test();
+ IF (from_left != 0 && sub(*bp, pc->b_left) == 0)
+ {
+ IF (pc->sim_dec == 1)
+ {
+ pc->b_left = *bp;
+ Dyn_Mem_Deluxe_Out();
+ return 1;
+ }
+ *bp = 0; move16();
+ pc->c_bp = 1; move16();
+ }
+ test();
+ IF (from_left == 0 && sub(bp_side_local, pc->b_right) == 0)
+ {
+ *bp_side = sub(pc->bytes, 1);
+ move16();
+ pc->c_bp_side = 1;
+ move16();
+ }
+ IF (sub(pc->bfi, 2) == 0)
+ {
+ test();
+ test();
+ IF ((pc->c_bp != 0 && sub(*bp, pc->be_bp_left) >= 0) ||
+ (pc->c_bp_side != 0 && sub(*bp_side, pc->be_bp_right) <= 0))
+ {
+ pc->inv_bin = cur_bin;
+ move16();
+ Dyn_Mem_Deluxe_Out();
+ return 1;
+ }
+ ELSE IF ((pc->c_bp != 0 && *bp >= 0) || (pc->c_bp_side != 0 && sub(*bp_side, sub(pc->bytes, 1)) <= 0))
+ {
+ pc->inv_bin = s_min(pc->inv_bin, cur_bin);
+ Dyn_Mem_Deluxe_Out();
+ return 0;
+ }
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return 0;
+}
+
diff --git a/lib_lc3plus/attack_detector_fx.c b/lib_lc3plus/attack_detector_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c62f849405daf62e1c5eee0caa2f15c1b9a983f
--- /dev/null
+++ b/lib_lc3plus/attack_detector_fx.c
@@ -0,0 +1,119 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch)
+{
+ Dyn_Mem_Deluxe_In(
+ int i, j, position;
+ Word32 tmp, *block_energy;
+ Word16 h16, l16, new_scaling, rescale, input_delta_scaling;
+ Word16 scales[3], *input_16k;
+ Word16 frame_length_16k;
+ );
+
+ block_energy = scratchAlign(scratch, 0);
+ input_16k = scratchAlign(block_energy, 4 * 4 + 4);
+ frame_length_16k = DEPR_i_mult(enc->attdec_nblocks, 40);
+
+ IF (setup->attack_handling)
+ {
+ /* input scaling */
+ scales[0] = add(getScaleFactor16(input, enc->frame_length), input_scaling);
+ scales[1] = add(getScaleFactor16_0(setup->attdec_filter_mem, 2), setup->attdec_scaling);
+ scales[2] =
+ shr(add(add(getScaleFactor32_0(&setup->attdec_acc_energy, 1), shl(setup->attdec_scaling, 1)), 1), 1);
+ new_scaling = s_min(scales[0], s_min(scales[1], scales[2]));
+
+ new_scaling = sub(new_scaling, 2); /* add overhead for resampler*/
+
+ /* memory re-scaling */
+ rescale = sub(new_scaling, setup->attdec_scaling);
+
+ IF (rescale)
+ {
+ rescale = s_min(s_max(rescale, -15), 15);
+ setup->attdec_filter_mem[0] = shl(setup->attdec_filter_mem[0], rescale); move16();
+ setup->attdec_filter_mem[1] = shl(setup->attdec_filter_mem[1], rescale); move16();
+ setup->attdec_acc_energy = L_shl(setup->attdec_acc_energy, shl(rescale, 1)); move16();
+ }
+ setup->attdec_scaling = new_scaling; move16();
+
+ SWITCH (enc->fs)
+ {
+ case 32000:
+ input_delta_scaling = sub(1, sub(new_scaling, input_scaling));
+ FOR (i = 0; i < frame_length_16k; i++)
+ {
+ input_16k[i] = add(shr(input[2 * i + 0], input_delta_scaling),
+ shr(input[2 * i + 1], input_delta_scaling)); move16();
+ }
+ break;
+ case 48000:
+ input_delta_scaling = sub(2, sub(new_scaling, input_scaling));
+ FOR (i = 0; i < frame_length_16k; i++)
+ {
+ input_16k[i] = add(shr(input[3 * i + 0], input_delta_scaling),
+ add(shr(input[3 * i + 1], input_delta_scaling),
+ shr(input[3 * i + 2], input_delta_scaling))); move16();
+ }
+ break;
+ default: ASSERT(!"sampling rate not supported in function attack_detector_fx!"); break;
+ }
+
+ input_16k[-2] = setup->attdec_filter_mem[0]; move16();
+ input_16k[-1] = setup->attdec_filter_mem[1]; move16();
+ setup->attdec_filter_mem[0] = input_16k[frame_length_16k - 2]; move16();
+ setup->attdec_filter_mem[1] = input_16k[frame_length_16k - 1]; move16();
+
+ FOR (i = frame_length_16k - 1; i >= 0; i--)
+ {
+ tmp = L_mult(input_16k[i], 12288);
+ tmp = L_msu(tmp, input_16k[i - 1], 16384);
+ tmp = L_mac(tmp, input_16k[i - 2], 4096);
+
+ input_16k[i] = extract_h(tmp); move16();
+ }
+
+ basop_memset(block_energy, 0, 4 * sizeof(Word32));
+
+ FOR (j = 0; j < enc->attdec_nblocks; j++)
+ {
+ FOR (i = 0; i < 40; i++)
+ {
+ block_energy[j] = L_mac(block_energy[j], input_16k[i + j*40], input_16k[i + j*40]); move16();
+ }
+ }
+
+ setup->attdec_detected = setup->attdec_position >= enc->attdec_hangover_thresh;
+ test(); move16();
+ position = -1; move16();
+
+ FOR (i = 0; i < enc->attdec_nblocks; i++)
+ {
+ /* block_energy[i] / 8.5 */
+ l16 = extract_l(L_shr(block_energy[i], 1));
+ l16 = s_and(l16, 0x7fff);
+ h16 = extract_h(block_energy[i]);
+ tmp = L_shr(L_mult0(l16, 30840), 15);
+ tmp = L_shr(L_mac0(tmp, h16, 30840), 2);
+
+ IF (tmp > setup->attdec_acc_energy)
+ {
+ position = i; move16();
+ setup->attdec_detected = 1; move16();
+ }
+ setup->attdec_acc_energy = L_max(L_shr(setup->attdec_acc_energy, 2), block_energy[i]); move16();
+ }
+ setup->attdec_position = position; move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
diff --git a/lib_lc3plus/basop_mpy_lc3plus.c b/lib_lc3plus/basop_mpy_lc3plus.c
new file mode 100644
index 0000000000000000000000000000000000000000..88a6d336bb1408357c6761888b8bd3e7be2e460d
--- /dev/null
+++ b/lib_lc3plus/basop_mpy_lc3plus.c
@@ -0,0 +1,99 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE
+Word32 Mpy_32_32_0(Word32 x, Word32 y)
+{
+ Word32 z;
+
+ z = L_shr(L_add(Mpy_32_32_lc3plus(x, y),1), 1);
+
+ return (z);
+}
+
+Word32 Mpy_32_16_0(Word32 x, Word16 y)
+{
+ Word32 z;
+
+ z = L_shr(L_add(Mpy_32_16_lc3plus(x, y),1), 1);
+
+ return (z);
+}
+#endif
+
+Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y)
+{
+ Word32 mh;
+ UWord16 ml;
+
+ Mpy_32_16_ss(x, y, &mh, &ml);
+
+ return (mh);
+}
+
+
+Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y)
+{
+ Word32 mh;
+ UWord32 ml;
+
+ Mpy_32_32_ss(x, y, &mh, &ml);
+
+ return (mh);
+}
+
+
+void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re,
+ const Word16 b_Im)
+{
+ *c_Re = L_sub(Mpy_32_16_lc3plus(a_Re, b_Re), Mpy_32_16_lc3plus(a_Im, b_Im)); move32();
+ *c_Im = L_add(Mpy_32_16_lc3plus(a_Re, b_Im), Mpy_32_16_lc3plus(a_Im, b_Re)); move32();
+}
+
+void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re,
+ const Word32 b_Im)
+{
+ *c_Re = L_sub(Mpy_32_32_lc3plus(a_Re, b_Re), Mpy_32_32_lc3plus(a_Im, b_Im)); move32();
+ *c_Im = L_add(Mpy_32_32_lc3plus(a_Re, b_Im), Mpy_32_32_lc3plus(a_Im, b_Re)); move32();
+}
+
+#ifdef ENABLE_HR_MODE
+Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y)
+{
+ z = L_add(z, Mpy_32_16_0(x, y));
+
+ return (z);
+}
+
+Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y)
+{
+ z = L_add(z, Mpy_32_32_0(x, y));
+
+ return (z);
+}
+
+Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y)
+{
+ z = L_sub(z, Mpy_32_16_0(x, y));
+
+ return (z);
+}
+
+Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y)
+{
+ z = L_sub(z, Mpy_32_32_0(x, y));
+
+ return (z);
+}
+
+#endif /* #ifdef ENABLE_HR_MODE */
diff --git a/lib_lc3plus/basop_mpy_lc3plus.h b/lib_lc3plus/basop_mpy_lc3plus.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c08755eea6d264a98496518630b97abe19370a9
--- /dev/null
+++ b/lib_lc3plus/basop_mpy_lc3plus.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+
+#ifndef __BASOP_MPY_H
+#define __BASOP_MPY_H
+
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE
+Word32 Mpy_32_16_0(Word32 x, Word16 y);
+#endif
+
+Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y);
+Word32 Mpy_32_32_0(Word32 x, Word32 y);
+Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y);
+Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y);
+Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y);
+
+/**
+ * \brief 32*16 Bit fractional Multiplication using 40 bit OPS
+ * Performs a multiplication of a 32-bit variable x by
+ * a 16-bit variable y, returning a 32-bit value.
+ *
+ * \param[i] x
+ * \param[i] y
+ *
+ * \return x*y
+ */
+Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y);
+
+/**
+ * \brief 32*32 Bit fractional Multiplication using 40 bit OPS
+ *
+ * Performs a multiplication of a 32-bit variable x by
+ * a 32-bit variable y, returning a 32-bit value.
+ *
+ * \param[i] x
+ * \param[i] y
+ *
+ * \return x*y
+ */
+Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y);
+
+#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+
+# ifdef ENABLE_HR_MODE
+# define cplxMpy32_32_32_2(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \
+ im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \
+ } while (0)
+# endif
+# define cplxMpy32_32_16_2(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \
+ im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \
+ } while (0)
+
+
+#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+# ifdef ENABLE_HR_MODE
+# define cplxMpy32_32_32_2(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \
+ im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \
+ } while (0)
+# endif
+# define cplxMpy32_32_16_2(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \
+ im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \
+ } while (0)
+
+#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re,
+ const Word16 b_Im);
+void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re,
+ const Word32 b_Im);
+
+#endif /* __BASOP_SETTINGS_H */
diff --git a/lib_lc3plus/basop_util_lc3plus.c b/lib_lc3plus/basop_util_lc3plus.c
new file mode 100644
index 0000000000000000000000000000000000000000..55a9b9eb1006813e495526fba823d5ee979d1305
--- /dev/null
+++ b/lib_lc3plus/basop_util_lc3plus.c
@@ -0,0 +1,1069 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+#include "rom_basop_util.h"
+#include "basop_util_lc3plus.h"
+
+extern const Word32 SqrtTable_lc3plus[32];
+extern const Word16 SqrtDiffTable_lc3plus[32];
+
+extern const Word32 ISqrtTable_lc3plus[32];
+extern const Word16 ISqrtDiffTable_lc3plus[32];
+
+extern const Word32 InvTable_lc3plus[32];
+extern const Word16 InvDiffTable_lc3plus[32];
+
+Word32 BASOP_Util_Log2_lc3plus(Word32 x)
+{
+ Word32 exp;
+ Word16 exp_e;
+ Word16 nIn;
+ Word16 accuSqr;
+ Word32 accuRes;
+
+ assert(x >= 0);
+
+ if (x == 0)
+ {
+
+ return ((Word32)MIN_32);
+ }
+
+ /* normalize input, calculate integer part */
+ exp_e = norm_l(x);
+ x = L_shl(x, exp_e);
+ exp = L_deposit_l(exp_e);
+
+ /* calculate (1-normalized_input) */
+ nIn = extract_h(L_sub(MAX_32, x));
+
+ /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */
+
+ /* iteration 1, no need for accumulation */
+ accuRes = L_mult(nIn, ldCoeff_lc3plus[0]); /* nIn^i * coeff[0] */
+ accuSqr = mult(nIn, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 2 */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[1]); /* nIn^i * coeff[1] */
+ accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 3 */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[2]); /* nIn^i * coeff[2] */
+ accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 4 */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[3]); /* nIn^i * coeff[3] */
+ accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 5 */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[4]); /* nIn^i * coeff[4] */
+ accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 6 */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[5]); /* nIn^i * coeff[5] */
+ accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */
+
+ /* iteration 7, no need to calculate accuSqr any more */
+ accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[6]); /* nIn^i * coeff[6] */
+
+ /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */
+ accuRes = L_mac0(L_shr(accuRes, 1), extract_h(accuRes), 14506);
+
+ accuRes = L_shr(accuRes, LD_DATA_SCALE - 1); /* fractional part/LD_DATA_SCALE */
+ exp = L_shl(exp, (31 - LD_DATA_SCALE)); /* integer part/LD_DATA_SCALE */
+ accuRes = L_sub(accuRes, exp); /* result = integer part + fractional part */
+
+ return (accuRes);
+}
+
+Word32 BASOP_Util_InvLog2_lc3plus(Word32 x)
+{
+#ifdef ENABLE_HR_MODE
+ /* Original code was used for negative x and hence the exp was always 0, which is assumed */
+ Word16 exp;
+ return BASOP_Util_InvLog2_pos(x, &exp);
+#else
+ Word16 frac;
+ Word16 exp;
+ Word32 retVal;
+ UWord32 index3;
+ UWord32 index2;
+ UWord32 index1;
+ UWord32 lookup3f;
+ UWord32 lookup12;
+ UWord32 lookup;
+
+ if (x < -1040187392l /*-31.0/64.0 Q31*/)
+ {
+
+ return 0;
+ }
+ test();
+ if ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0) || (x == 0))
+ {
+
+ return 0x7FFFFFFF;
+ }
+
+ frac = extract_l(L_and(x, 0x3FF));
+
+ index3 = L_and(L_shr_pos(x, 10), 0x1F);
+ index2 = L_and(L_shr_pos(x, 15), 0x1F);
+ index1 = L_and(L_shr_pos(x, 20), 0x1F);
+
+ exp = extract_l(L_shr_pos(x, 25));
+ if (x > 0)
+ {
+ exp = sub(31, exp);
+ }
+ if (x < 0)
+ {
+ exp = negate(exp);
+ }
+
+ lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr_pos(Mpy_32_16_lc3plus(0x0016302F, frac), 1));
+ lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]);
+ lookup = Mpy_32_32_lc3plus(lookup12, lookup3f);
+
+ retVal = L_shr(lookup, sub(exp, 3));
+
+ return retVal;
+#endif
+}
+
+#ifdef ENABLE_HR_MODE
+/* New function which works with positive and negative exponents */
+Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp)
+{
+ Word16 frac;
+ Word16 ret_exp;
+ Word32 retVal;
+ UWord32 index3;
+ UWord32 index2;
+ UWord32 index1;
+ UWord32 lookup3f;
+ UWord32 lookup12;
+ UWord32 lookup;
+
+ /* The usage of exp.mantissa format in LC3plus in Word32 is : floatval = mantissa / (2^(31 - exp)) */
+ ret_exp = extract_l(L_shr(x, 25));
+
+ IF (x < -1040187392l /*-31.0/64.0 Q31*/)
+ {
+ *exp = 0;
+ move16();
+ return 0;
+ }
+ test();
+ IF ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0))
+ {
+ *exp = 31;
+ move16();
+ return 0x40000000;
+ }
+ ELSE IF(x == 0)
+ {
+ *exp = -1;
+ move16();
+ return 0x10000000;
+ }
+
+ frac = extract_l(L_and(x, 0x3FF));
+
+ index3 = L_and(L_shr(x, 10), 0x1F);
+ index2 = L_and(L_shr(x, 15), 0x1F);
+ index1 = L_and(L_shr(x, 20), 0x1F);
+
+ lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr(Mpy_32_16_lc3plus(0x0016302F, frac), 1));
+ lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]);
+ lookup = Mpy_32_32_lc3plus(lookup12, lookup3f);
+
+ IF (x > 0)
+ {
+ /* The returned exponent is the offset from 31, so the float result is
+ retVal / 2^(31 - *exp) */
+ *exp = add(ret_exp, 3);
+ retVal = lookup;
+ }
+ ELSE
+ {
+ /* For negative powers provide the result in Q31 and ignore the exponent */
+ *exp = 0;
+ retVal = L_shr(lookup, sub(negate(ret_exp), 3));
+ }
+
+ return retVal;
+}
+#endif
+
+/* local function for Sqrt16_lc3plus and Sqrt16norm */
+static Word16 Sqrt16_common(Word16 m, Word16 e)
+{
+ Word16 index, frac;
+
+ assert((m >= 0x4000) || (m == 0));
+
+ /* get table index (upper 6 bits minus 32) */
+ /* index = (m >> 9) - 32; */
+ index = mac_r(-32768 - (32 << 16), m, 1 << 6);
+
+ /* get fractional part for interpolation (lower 9 bits) */
+ frac = s_and(m, 0x1FF); /* Q9 */
+
+ /* interpolate */
+ if (m != 0)
+ {
+ m = mac_r(SqrtTable_lc3plus[index], SqrtDiffTable_lc3plus[index], frac);
+ }
+
+ /* handle odd exponents */
+ if (s_and(e, 1) != 0)
+ m = mult_r(m, 0x5a82);
+
+ return m;
+}
+
+/* local function for ISqrt16 and ISqrt16norm */
+static Word16 ISqrt16_common(Word16 m, Word16 e)
+{
+ Word16 index, frac;
+
+ assert(m >= 0x4000);
+
+ /* get table index (upper 6 bits minus 32) */
+ /* index = (m >> 9) - 32; */
+ index = mac_r(-32768 - (32 << 16), m, 1 << 6);
+
+ /* get fractional part for interpolation (lower 9 bits) */
+ frac = s_and(m, 0x1FF); /* Q9 */
+
+ /* interpolate */
+ m = msu_r(ISqrtTable_lc3plus[index], ISqrtDiffTable_lc3plus[index], frac);
+
+ /* handle even exponents */
+ if (s_and(e, 1) == 0)
+ m = mult_r(m, 0x5a82);
+
+ return m;
+}
+
+Word16 Sqrt16_lc3plus( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+)
+{
+ Word16 preShift, e;
+
+ assert(mantissa >= 0);
+
+ /* normalize */
+ preShift = norm_s(mantissa);
+
+ e = sub(*exponent, preShift);
+ mantissa = shl(mantissa, preShift);
+
+ /* calc mantissa */
+ mantissa = Sqrt16_common(mantissa, e);
+
+ /* e = (e + 1) >> 1 */
+ *exponent = mult_r(e, 1 << 14); move16();
+
+ return mantissa;
+}
+
+Word16 ISqrt16( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+)
+{
+ Word16 preShift, e;
+
+ assert(mantissa > 0);
+
+ /* normalize */
+ preShift = norm_s(mantissa);
+
+ e = sub(*exponent, preShift);
+ mantissa = shl(mantissa, preShift);
+
+ /* calc mantissa */
+ mantissa = ISqrt16_common(mantissa, e);
+
+ /* e = (2 - e) >> 1 */
+ *exponent = msu_r(1L << 15, e, 1 << 14); move16();
+
+ return mantissa;
+}
+
+Word16 Inv16_lc3plus( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+)
+{
+ Word16 index, frac;
+ Word16 preShift;
+ Word16 m, e;
+
+ assert(mantissa != 0);
+
+ /* absolute */
+ m = abs_s(s_max(mantissa, MIN_16 + 1));
+
+ /* normalize */
+ preShift = norm_s(m);
+
+ e = sub(*exponent, preShift);
+ m = shl(m, preShift);
+
+ /* get table index (upper 6 bits minus 32) */
+ /* index = (m >> 9) - 32; */
+ index = mac_r(-32768 - (32 << 16), m, 1 << 6);
+
+ /* get fractional part for interpolation (lower 9 bits) */
+ frac = shl(s_and(m, 0x1FF), 1); /* Q10 */
+
+ /* interpolate */
+ m = msu_r(InvTable_lc3plus[index], InvDiffTable_lc3plus[index], frac);
+
+ /* restore sign */
+ if (mantissa < 0)
+ m = negate(m);
+
+ /* e = 1 - e */
+ *exponent = sub(1, e); move16();
+
+ return m;
+}
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x
+*/
+
+Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
+ const Word16 *x, /* i: array containing 16-bit data */
+ const Word16 len_x) /* i: length of the array to scan */
+{
+ Counter i;
+ Word16 i_min, i_max;
+ Word16 x_min, x_max;
+
+ x_max = 0; move16();
+ x_min = 0; move16();
+ FOR (i = 0; i < len_x; i++)
+ {
+ if (x[i] >= 0)
+ x_max = s_max(x_max, x[i]);
+ if (x[i] < 0)
+ x_min = s_min(x_min, x[i]);
+ }
+
+ i_max = 0x10; move16();
+ i_min = 0x10; move16();
+
+ if (x_max != 0)
+ i_max = norm_s(x_max);
+
+ if (x_min != 0)
+ i_min = norm_s(x_min);
+
+ i = s_and(s_min(i_max, i_min), 0xF);
+
+ return i;
+}
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x
+*/
+
+Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */
+ const Word16 *x, /* i: array containing 16-bit data */
+ const Word16 len_x) /* i: length of the array to scan */
+{
+ Counter i;
+ Word16 i_min, i_max;
+ Word16 x_min, x_max;
+
+ x_max = 0; move16();
+ x_min = 0; move16();
+ FOR (i = 0; i < len_x; i++)
+ {
+ if (x[i] >= 0)
+ x_max = s_max(x_max, x[i]);
+ if (x[i] < 0)
+ x_min = s_min(x_min, x[i]);
+ }
+
+ i_max = 0x10; move16();
+ i_min = 0x10; move16();
+
+ if (x_max != 0)
+ i_max = norm_s(x_max);
+
+ if (x_min != 0)
+ i_min = norm_s(x_min);
+
+ i = s_min(i_max, i_min);
+
+ return i;
+}
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x
+*/
+
+Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
+ const Word32 *x, /* i: array containing 32-bit data */
+ const Word16 len_x) /* i: length of the array to scan */
+{
+ Counter i;
+ Word16 i_min, i_max;
+ Word32 x_min, x_max;
+
+ x_max = L_add(0, 0);
+ x_min = L_add(0, 0);
+ FOR (i = 0; i < len_x; i++)
+ {
+ if (x[i] >= 0)
+ x_max = L_max(x_max, x[i]);
+ if (x[i] < 0)
+ x_min = L_min(x_min, x[i]);
+ }
+
+ i_max = 0x20; move16();
+ i_min = 0x20; move16();
+
+ if (x_max != 0)
+ i_max = norm_l(x_max);
+
+ if (x_min != 0)
+ i_min = norm_l(x_min);
+
+ i = s_and(s_min(i_max, i_min), 0x1F);
+
+ return i;
+}
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x
+*/
+
+Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */
+ const Word32 *x, /* i: array containing 32-bit data */
+ const Word16 len_x) /* i: length of the array to scan */
+{
+ Counter i;
+ Word16 i_min, i_max;
+ Word32 x_min, x_max;
+
+ x_max = L_add(0, 0);
+ x_min = L_add(0, 0);
+ FOR (i = 0; i < len_x; i++)
+ {
+ if (x[i] >= 0)
+ x_max = L_max(x_max, x[i]);
+ if (x[i] < 0)
+ x_min = L_min(x_min, x[i]);
+ }
+
+ i_max = 0x20; move16();
+ i_min = 0x20; move16();
+
+ if (x_max != 0)
+ i_max = norm_l(x_max);
+
+ if (x_min != 0)
+ i_min = norm_l(x_min);
+
+ i = s_min(i_max, i_min);
+
+ return i;
+}
+
+Word16 BASOP_Util_Divide3216_Scale_lc3plus( /* o: result of division x/y, not normalized */
+ Word32 x, /* i: numerator, signed */
+ Word16 y, /* i: denominator, signed */
+ Word16 *s) /* o: scaling, 0, if x==0 */
+{
+ Word16 z;
+ Word16 sx;
+ Word16 sy;
+ Word16 sign;
+
+ /*assert (x > (Word32)0);
+ assert (y >= (Word16)0);*/
+
+ /* check, if numerator equals zero, return zero then */
+ IF (x == (Word32)0)
+ {
+ *s = 0; move16();
+
+ return ((Word16)0);
+ }
+
+ sign = s_xor(extract_h(x), y); /* just to exor the sign bits */
+ x = L_abs(L_max(x, MIN_32 + 1));
+ y = abs_s(s_max(y, MIN_16 + 1));
+ sx = sub(norm_l(x), 1);
+ x = L_shl(x, sx);
+ sy = norm_s(y);
+ y = shl(y, sy);
+ *s = sub(sy, sx); move16();
+
+ z = div_s(round_fx(x), y);
+
+ if (sign < 0) /* if sign bits differ, negate the result */
+ {
+ z = negate(z);
+ }
+
+ return z;
+}
+
+Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, Word16 y, Word16 *s)
+{
+ Word16 z;
+ Word16 sx;
+ Word16 sy;
+ Word16 sign;
+
+ /* assert (x >= (Word16)0); */
+ assert(y != (Word16)0);
+
+ sign = 0; move16();
+
+ IF (x < 0)
+ {
+ x = negate(x);
+ sign = s_xor(sign, 1);
+ }
+
+ IF (y < 0)
+ {
+ y = negate(y);
+ sign = s_xor(sign, 1);
+ }
+
+ IF (x == (Word16)0)
+ {
+ *s = 0; move16();
+
+ return ((Word16)0);
+ }
+
+ sx = norm_s(x);
+ x = shl(x, sx);
+ x = shr(x, 1);
+ *s = sub(1, sx); move16();
+
+ sy = norm_s(y);
+ y = shl(y, sy);
+ *s = add(*s, sy); move16();
+
+ z = div_s(x, y);
+
+ if (sign != 0)
+ {
+ z = negate(z);
+ }
+
+ return z;
+}
+
+Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e)
+{
+ Word32 L_tmp, L_tmp2, inc;
+ Word16 s, shift, tmp;
+ Counter i;
+
+ shift = headroom; move16();
+
+ L_tmp = L_deposit_l(0);
+
+ FOR (i = 0; i < length; i++)
+ {
+ L_tmp2 = L_sub(L_tmp, 0x40000000);
+ if (L_tmp2 >= 0)
+ shift = sub(shift, 1);
+ if (L_tmp2 >= 0)
+ L_tmp = L_shr(L_tmp, 2);
+
+ tmp = round_fx_sat(L_shl_sat(x[i], shift));
+ L_tmp = L_mac0(L_tmp, tmp, tmp); /* exponent = (1-shift*2) , Q(30+shift*2) */
+ }
+
+ /* Consider an increase of 0xfffd per sample in case that the pre-shift factor
+ in the acf is 1 bit higher than the shift factor estimated in this function.
+ This prevent overflows in the acf. */
+ IF (L_tmp != 0)
+ {
+ s = norm_s(length);
+ inc = L_shl(Mpy_32_16_lc3plus(0x0000fffd, shl(length, s)), sub(15, s));
+ L_tmp = L_add_sat(L_tmp, inc);
+ }
+
+ *result_e = sub(1, shl(shift, 1)); move16();
+
+ return L_tmp;
+}
+
+void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+)
+{
+ Counter i;
+ Word16 tmp;
+ IF (exp0 > 0)
+ {
+ tmp = s_min(exp0, 15); move16();
+ FOR (i = 0; i < lg; i++)
+ {
+ x[i] = shl(x[i], tmp); move16(); /* saturation can occur here */
+ }
+ return;
+ }
+ IF (exp0 < 0)
+ {
+ tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */
+ FOR (i = 0; i < lg; i++)
+ {
+ x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */
+ }
+ return;
+ }
+}
+
+void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */
+ Word16 y[], /* o : scaled signal output Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+)
+{
+ Counter i;
+ Word16 tmp;
+
+ IF (exp0 == 0)
+ {
+ basop_memmove(y, x, lg * sizeof(Word16));
+
+ return;
+ }
+ IF (exp0 < 0)
+ {
+ tmp = shl(-32768, exp0); /* we use negative to correctly represent 1.0 */
+ FOR (i = 0; i < lg; i++)
+ {
+ y[i] = msu_r(0, x[i], tmp); move16();
+ }
+ return;
+ }
+ FOR (i = 0; i < lg; i++)
+ {
+ y[i] = shl_sat(x[i], exp0); move16(); /* saturation can occur here */
+ }
+}
+
+Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */
+ (Word32 a_m, /*!< i: Mantissa of 1st operand a */
+ Word16 a_e, /*!< i: Exponent of 1st operand a */
+ Word32 b_m, /*!< i: Mantissa of 2nd operand b */
+ Word16 b_e, /*!< i: Exponent of 2nd operand b */
+ Word16 *ptr_e) /*!< o: exponent of result */
+{
+ Word32 L_tmp;
+ Word16 shift;
+
+ /* Compare exponents: the difference is limited to +/- 30
+ The Word32 mantissa of the operand with lower exponent is shifted right by the exponent difference.
+ Then, the unshifted mantissa of the operand with the higher exponent is added. The addition result
+ is normalized and the result represents the mantissa to return. The returned exponent takes into
+ account all shift operations.
+ */
+
+ if (!a_m)
+ a_e = add(b_e, 0);
+
+ if (!b_m)
+ b_e = add(a_e, 0);
+
+ shift = sub(a_e, b_e);
+ shift = s_max(-31, shift);
+ shift = s_min(31, shift);
+ if (shift < 0)
+ {
+ /* exponent of b is greater than exponent of a, shr a_m */
+ a_m = L_shl(a_m, shift);
+ }
+ if (shift > 0)
+ {
+ /* exponent of a is greater than exponent of b */
+ b_m = L_shr(b_m, shift);
+ }
+ a_e = add(s_max(a_e, b_e), 1);
+ L_tmp = L_add(L_shr(a_m, 1), L_shr(b_m, 1));
+ shift = norm_l(L_tmp);
+ if (shift)
+ L_tmp = L_shl(L_tmp, shift);
+ if (L_tmp == 0)
+ a_e = add(0, 0);
+ if (L_tmp != 0)
+ a_e = sub(a_e, shift);
+ *ptr_e = a_e;
+
+ return (L_tmp);
+}
+
+Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */
+ /* 0, if a == b */
+ /* 1, if a > b */
+ /* -1, if a < b */
+ (Word32 a_m, /*!< i: Mantissa of 1st operand a */
+ Word16 a_e, /*!< i: Exponent of 1st operand a */
+ Word32 b_m, /*!< i: Mantissa of 2nd operand b */
+ Word16 b_e) /*!< i: Exponent of 2nd operand b */
+
+{
+ Word32 diff_m;
+ Word16 diff_e, shift, result;
+
+ /*
+ This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent.
+ If both values are identical, 0 is returned.
+ If a is greater b, 1 is returned.
+ If a is less than b, -1 is returned.
+ */
+
+ /* Check, if both mantissa and exponents are identical, when normalized: return 0 */
+ shift = norm_l(a_m);
+ if (shift)
+ a_m = L_shl(a_m, shift);
+ if (shift)
+ a_e = sub(a_e, shift);
+
+ shift = norm_l(b_m);
+ if (shift)
+ b_m = L_shl(b_m, shift);
+ if (shift)
+ b_e = sub(b_e, shift);
+
+ /* align exponent, if any mantissa is zero */
+ if (!a_m)
+ a_e = add(b_e, 0);
+ if (!b_m)
+ b_e = add(a_e, 0);
+
+ IF (a_m > 0 && b_m < 0)
+ {
+ diff_m = 1; move16();
+ }
+ ELSE IF (a_m<0 && b_m> 0)
+ {
+ diff_m = -1; move16();
+ }
+ ELSE
+ {
+ diff_m = L_sub(a_m, b_m);
+ }
+
+ diff_e = sub(a_e, b_e);
+
+ test();
+ IF (diff_m == 0 && diff_e == 0)
+ {
+ return 0;
+ }
+
+ /* Check sign, exponent and mantissa to identify, whether a is greater b or not */
+ result = sub(0, 1);
+
+ IF (a_m >= 0)
+ {
+ /* a is positive */
+ if (b_m < 0)
+ {
+ result = add(1, 0);
+ }
+
+ test(); test(); test();
+ if ((b_m >= 0) && ((diff_e > 0) || (diff_e == 0 && diff_m > 0)))
+ {
+ result = add(1, 0);
+ }
+ }
+ ELSE
+ {
+ /* a is negative */
+ test(); test(); test();
+ if ((b_m < 0) && ((diff_e < 0) || (diff_e == 0 && diff_m > 0)))
+ {
+ result = add(1, 0);
+ }
+ }
+ return result;
+}
+
+/*----------------------------------------------------------------------------------*
+ * Function: Isqrt
+ *
+ * Description:
+ *
+ * The function computes 1/sqrt(x).
+ * The mantissa of the input value must be in the range of 1.0 > x >= 0.5.
+ * The computation of the inverse square root is an approach with a lookup table
+ * and linear interpolation.
+ *
+ * result = x * 2^x_e
+ *
+ * Parameter:
+ *
+ * x [i] mantissa (Q31)
+ * x_e [i/o] pointer to exponent (Q0)
+ *
+ * Return value:
+ *
+ * mantissa (Q31)
+ *
+ *----------------------------------------------------------------------------------*/
+Word32 Isqrt(Word32 x, /* mantissa */
+ Word16 *x_e /* pointer to exponent */
+)
+{
+ Word16 s;
+ Word32 y;
+ Word32 idx;
+ Word32 diff;
+ Word16 fract;
+
+ IF (x <= 0)
+ {
+ *x_e = 0; move16();
+ return 0x7FFFFFFF;
+ }
+
+ /* check if exponent is odd */
+ s = s_and(*x_e, 0x0001);
+
+ /* get table index (upper 8 bits) */
+ idx = L_and(L_shr(x, (31 - 8)), 0x00000007f);
+
+ /* get fractional part for interpolation (lower 23 bits) */
+ fract = extract_h(L_shl(L_and(x, 0x007FFFFF), 8));
+
+ /* interpolate */
+ diff = L_sub(isqrt_table[idx + 1], isqrt_table[idx]);
+ y = L_add(isqrt_table[idx], Mpy_32_16_lc3plus(diff, fract));
+
+ /* if exponent is odd apply sqrt(0.5) */
+ if (s != 0)
+ {
+ y = Mpy_32_16_lc3plus(y, 0x5A82 /*0x5A827999*/);
+ }
+
+ /* if exponent is odd shift 1 bit left */
+ if (s != 0)
+ {
+ y = L_shl(y, s);
+ }
+
+ /* change sign, shift right and add 1 to exponent (implicit exponent of isqrt_table) */
+ *x_e = mac_r(32768, *x_e, -16384); move16();
+
+ return y;
+}
+
+Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e)
+{
+ Word16 shift, tmp1, tmp2;
+ Word16 outInt, outFrac, out;
+
+ assert(x >= 0);
+
+ if (x == 0)
+ {
+ return (MIN_16);
+ }
+
+ /* Scale Input */
+ shift = norm_l(x);
+ x = L_shl(x, sub(shift, 10));
+
+ /* Integer part */
+ outInt = shl(sub(sub(x_e, shift), 1), 9);
+
+ /* Fractional part */
+ tmp1 = mac_r(x, -33, 16384);
+ tmp2 = lshr(extract_l(x), 6);
+ outFrac = mac_r(Log2_16_table1[tmp1], Log2_16_table2[tmp1], tmp2);
+
+ /* Output */
+ out = add(outInt, outFrac);
+
+ return out;
+}
+
+Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e)
+{
+ Word16 tmp1, tmp2, y;
+
+ tmp1 = shr(s_and(x, 2047), 5);
+ tmp2 = shl(s_and(x, 31), 4);
+ y = mac_r(InvLog2_16_table1[tmp1], InvLog2_16_table2[tmp1], tmp2);
+ *y_e = add(shr_pos(x, 11), 1);
+
+ return y;
+}
+
+#ifdef ENABLE_HR_MODE
+#define DFRACT_BITS 32 /* double precision */
+
+#define SQRT_BITS 7
+#define SQRT_BITS_MASK 0x7f
+#define SQRT_FRACT_BITS_MASK 0x007FFFFF
+
+#ifndef Word64
+#define Word64 long long
+#endif
+
+static __inline Word32 Mpy_32_32_noshift(Word32 x1, Word32 x2)
+{
+ Word64 ret = 0;
+ ret = ((Word64)x1 * (Word64)x2);
+ return ((Word32)((ret & (Word64)0xffffffff00000000) >> 32));
+}
+
+static __inline Word32 fixmadddiv2_DD(const Word32 x, const Word32 a, const Word32 b)
+{
+ return ((((Word64)x << 32) + (Word64)a * b) >> 32);
+}
+
+/**
+ * \brief calculate 1.0/sqrt(op)
+ * \param op_m mantissa of input value.
+ * \param result_e pointer to return the exponent of the result
+ * \return mantissa of the result
+ */
+/*****************************************************************************
+ delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT,
+ i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift)
+ uses Newton-iteration for approximation
+ Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2)
+ with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0
+*****************************************************************************/
+static __inline Word32 invSqrtNorm2(Word32 op, Word32 *shift)
+{
+ Word32 val = op;
+ Word32 reg1, reg2;
+
+ if (val == 0)
+ {
+ *shift = 16;
+ return ((Word32)0x7FFFFFFF); /* maximum positive value */
+ }
+
+/* #define INVSQRTNORM2_NEWTON_ITERATE */
+#define INVSQRTNORM2_LINEAR_INTERPOLATE
+#define INVSQRTNORM2_LINEAR_INTERPOLATE_HQ
+
+ /* normalize input, calculate shift value */
+ assert(val > 0);
+ *shift = norm_l(val); /* CountLeadingBits() is not necessary here since test value is always > 0 */
+ val <<= *shift; /* normalized input V */
+ *shift += 2; /* bias for exponent */
+
+#if defined(INVSQRTNORM2_NEWTON_ITERATE)
+ /* Newton iteration of 1/sqrt(V) */
+ reg1 = invSqrtTab[(Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK];
+ reg2 = FL2FXCONST_DBL(0.0625f); /* 0.5 >> 3 */
+
+ Word32 regtmp = fPow2Div2(reg1); /* a = Q^2 */
+ regtmp = reg2 - fMultDiv2(regtmp, val); /* b = 0.5 - 2 * V * Q^2 */
+ reg1 += (fMultDiv2(regtmp, reg1) << 4); /* Q = Q + Q*b */
+#elif defined(INVSQRTNORM2_LINEAR_INTERPOLATE)
+ Word32 index = (Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK;
+ Word32 Fract = (Word32)(((Word32)val & SQRT_FRACT_BITS_MASK) << (SQRT_BITS + 1));
+ Word32 diff = invSqrtTab[index + 1] - invSqrtTab[index];
+ reg1 = invSqrtTab[index] + (Word32)(((UWord32)(Mpy_32_32_noshift(diff, Fract)) << 1));
+#if defined(INVSQRTNORM2_LINEAR_INTERPOLATE_HQ)
+ /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ...
+ + (1-fract)fract*(t[i+2]-t[i+1])/2 */
+ if (Fract != (Word32)0)
+ {
+ /* fract = fract * (1 - fract) */
+ Fract = Mpy_32_32_noshift(Fract, (Word32)((UWord32)0x80000000 - (Word32)Fract)) << 1;
+ diff = diff - (invSqrtTab[index + 2] - invSqrtTab[index + 1]);
+ reg1 = fixmadddiv2_DD(reg1, Fract, diff);
+ }
+#endif /* INVSQRTNORM2_LINEAR_INTERPOLATE_HQ */
+#else
+#error "Either define INVSQRTNORM2_NEWTON_ITERATE or INVSQRTNORM2_LINEAR_INTERPOLATE"
+#endif
+ /* calculate the output exponent = input exp/2 */
+ if (*shift & 0x00000001)
+ { /* odd shift values ? */
+ /* Note: Do not use rounded value 0x5A82799A to avoid overflow with shift-by-2 */
+ reg2 = (Word32)0x5A827999; /* FL2FXCONST_DBL(0.707106781186547524400844362104849f);*/ /* 1/sqrt(2); */
+#ifdef __ADSP21000__
+ reg1 = fMult(reg1, reg2) << 1; /* compiler bug work around (CCES 2.4.0), and better precision */
+#else
+ reg1 = Mpy_32_32_noshift(reg1, reg2) << 2;
+#endif
+ }
+
+ *shift = *shift >> 1;
+
+ return (reg1);
+}
+
+/**
+ * \brief calculate 1.0/(op_m * 2^op_e)
+ * \param op_m mantissa of the input value.
+ * \param op_e pointer into were the exponent of the input value is stored, and the result will be stored into.
+ * \return mantissa of the result
+ */
+Word32 invFixp(Word32 op_m, Word16 *op_e)
+{
+ if ((op_m == (Word32)0x00000000) || (op_m == (Word32)0x00000001))
+ {
+ *op_e = 31 - *op_e;
+ return ((Word32)0x7FFFFFFF);
+ }
+
+ Word32 tmp_exp;
+ Word32 tmp_inv = invSqrtNorm2(op_m, &tmp_exp);
+
+ *op_e = (tmp_exp << 1) - *op_e + 1;
+ return Mpy_32_32_noshift(tmp_inv, tmp_inv);
+}
+#endif
diff --git a/lib_lc3plus/basop_util_lc3plus.h b/lib_lc3plus/basop_util_lc3plus.h
new file mode 100644
index 0000000000000000000000000000000000000000..99bc211a9972f942d4638c6f34f9706a7815758f
--- /dev/null
+++ b/lib_lc3plus/basop_util_lc3plus.h
@@ -0,0 +1,377 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef __BASOP_UTIL_LC3PLUS_H__
+#define __BASOP_UTIL_LC3PLUS_H__
+
+#include "defines.h"
+#include "functions.h"
+#include
+#include
+
+#define _LONG long
+#define _SHORT short
+#ifdef _WIN32
+#define _INT64 __int64
+#else
+#define _INT64 long long
+#endif
+
+#define WORD32_BITS 32
+#define MAXVAL_WORD32 ((signed)0x7FFFFFFF)
+#define MINVAL_WORD32 ((signed)0x80000000)
+#define WORD32_FIX_SCALE ((_INT64)(1) << (WORD32_BITS - 1))
+
+#define WORD16_BITS 16
+#define MAXVAL_WORD16 (((signed)0x7FFFFFFF) >> 16)
+#define MINVAL_WORD16 (((signed)0x80000000) >> 16)
+#define WORD16_FIX_SCALE ((_INT64)(1) << (WORD16_BITS - 1))
+
+/*!
+ \def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation
+*/
+#define WORD322WORD16(val) \
+ ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((_LONG)1 << WORD16_BITS) - 1)) && ((_LONG)(val) > 0)) \
+ ? (Word16)(_SHORT)(((_LONG)1 << (WORD16_BITS - 1)) - 1) \
+ : (Word16)(_SHORT)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1))
+
+
+/* Word16 Packed Type */
+typedef struct
+{
+ struct
+ {
+ Word16 re;
+ Word16 im;
+ } v;
+} PWord16;
+
+#ifdef ENABLE_HR_MODE
+/* Word32 Packed Type */
+typedef struct
+{
+ struct
+ {
+ Word32 re;
+ Word32 im;
+ } v;
+} PWord32;
+#endif
+
+#define cast16 move16
+
+#define LD_DATA_SCALE (6)
+#define LD_DATA_SHIFT_I5 (7)
+
+/************************************************************************/
+/*!
+ \brief Calculate the squareroot of a number given by mantissa and exponent
+
+ Mantissa is in 16/32-bit-fractional format with values between 0 and 1.
+ For *norm versions mantissa has to be between 0.5 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The exponent is addressed via pointers and will be overwritten with the result.
+*/
+
+Word16 Sqrt16_lc3plus( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+);
+
+Word16 ISqrt16( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+);
+
+/*****************************************************************************/
+/*!
+ \brief Calculate the inverse of a number given by mantissa and exponent
+
+ Mantissa is in 16-bit-fractional format with values between 0 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The operand is addressed via pointers and will be overwritten with the result.
+
+ The function uses a table lookup and a newton iteration.
+*/
+Word16 Inv16_lc3plus( /*!< output mantissa */
+ Word16 mantissa, /*!< input mantissa */
+ Word16 *exponent /*!< pointer to exponent */
+);
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x
+*/
+
+Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */
+ const Word16 *x, /* i: array containing 16-bit data */
+ const Word16 len_x); /* i: length of the array to scan */
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x
+*/
+
+Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */
+ const Word16 *x, /* i: array containing 16-bit data */
+ const Word16 len_x); /* i: length of the array to scan */
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x
+*/
+
+Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */
+ const Word32 *x, /* i: array containing 32-bit data */
+ const Word16 len_x); /* i: length of the array to scan */
+
+/********************************************************************/
+/*!
+ \brief Calculates the scalefactor needed to normalize input array
+
+ The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x
+*/
+
+Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */
+ const Word32 *x, /* i: array containing 32-bit data */
+ const Word16 len_x); /* i: length of the array to scan */
+
+/****************************************************************************/
+/*!
+ \brief Does fractional integer division of Word32 arg1 by Word16 arg2
+
+
+ \return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized
+*/
+Word16 BASOP_Util_Divide3216_Scale_lc3plus(Word32 x, /*!< i : Numerator */
+ Word16 y, /*!< i : Denominator*/
+ Word16 *s); /*!< o : Additional scalefactor difference*/
+
+/****************************************************************************/
+/*!
+ \brief Does fractional division of Word16 arg1 by Word16 arg2
+
+
+ \return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15) with scaling s
+*/
+Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, /*!< i : Numerator*/
+ Word16 y, /*!< i : Denominator*/
+ Word16 *s); /*!< o : Additional scalefactor difference*/
+
+/************************************************************************/
+/*!
+ \brief Binary logarithm with 7 iterations
+
+ \param x
+
+ \return log2(x)/64
+ */
+/************************************************************************/
+Word32 BASOP_Util_Log2_lc3plus(Word32 x);
+
+/************************************************************************/
+/*!
+ \brief Binary power
+
+ Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen
+
+ Version with 3 table lookup and 1 linear interpolations
+
+ Algorithm: compute power of 2, argument x is in Q7.25 format
+ result = 2^(x/64)
+ We split exponent (x/64) into 5 components:
+ integer part: represented by b31..b25 (exp)
+ fractional part 1: represented by b24..b20 (lookup1)
+ fractional part 2: represented by b19..b15 (lookup2)
+ fractional part 3: represented by b14..b10 (lookup3)
+ fractional part 4: represented by b09..b00 (frac)
+ => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp
+
+ Due to the fact, that all lookup values contain a factor 0.5
+ the result has to be shifted by 3 to the right also.
+ Table exp2_tab_long_lc3plus contains the log2 for 0 to 1.0 in steps
+ of 1/32, table exp2w_tab_long_lc3plus the log2 for 0 to 1/32 in steps
+ of 1/1024, table exp2x_tab_long_lc3plus the log2 for 0 to 1/1024 in
+ steps of 1/32768. Since the 2-logarithm of very very small
+ negative value is rather linear, we can use interpolation.
+
+ Limitations:
+
+ For x <= 0, the result is fractional positive
+ For x > 0, the result is integer in range 1...7FFF.FFFF
+ For x < -31/64, we have to clear the result
+ For x = 0, the result is ~1.0 (0x7FFF.FFFF)
+ For x >= 31/64, the result is 0x7FFF.FFFF
+
+ \param x
+
+ \return pow(2,(x/64))
+ */
+/************************************************************************/
+Word32 BASOP_Util_InvLog2_lc3plus(Word32 x);
+
+#ifdef ENABLE_HR_MODE
+/* New function which works with positive x, BASOP_Util_InvLog2_lc3plus does not give
+ accurate results for x > 0 */
+Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp);
+#endif
+
+/**
+ * \brief Compute dot product of 1 32 bit vectors with itself
+ * \param x input vector 1
+ * \param headroom amount of headroom bits the input vector
+ * \param length the length of the input vector
+ * \param result_e pointer to where the exponent of the result will be stored into
+ * \return the dot product of x and x.
+ */
+Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e);
+
+/*!**********************************************************************
+ \brief Add two values given by mantissa and exponent.
+
+ Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+
+************************************************************************/
+Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */
+ (Word32 a_m, /*!< i: Mantissa of 1st operand a */
+ Word16 a_e, /*!< i: Exponent of 1st operand a */
+ Word32 b_m, /*!< i: Mantissa of 2nd operand b */
+ Word16 b_e, /*!< i: Exponent of 2nd operand b */
+ Word16 *ptr_e); /*!< o: exponent of result */
+ /*!**********************************************************************
+ \brief Returns the comparison result of two normalized values given by mantissa and exponent.
+ return value: -1: a < b, 0: a == b, 1; a > b
+
+ Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+
+ ************************************************************************/
+Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */
+ (Word32 a_m, /*!< i: Mantissa of 1st operand a */
+ Word16 a_e, /*!< i: Exponent of 1st operand a */
+ Word32 b_m, /*!< i: Mantissa of 2nd operand b */
+ Word16 b_e); /*!< i: Exponent of 2nd operand b */
+
+/* compare two positive normalized 16 bit mantissa/exponent values */
+/* return value: positive if first value greater, negative if second value greater, zero if equal */
+Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2);
+
+void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+);
+void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */
+ Word16 y[], /* o : scaled signal output Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+);
+
+#ifdef ENABLE_HR_MODE
+void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */
+ Word16 y[], /* o : scaled signal output Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+);
+#endif
+
+Word32 Isqrt(Word32 x, /* (i) Q31: normalized value (1.0 > x >= 0.5) */
+ Word16 *x_e /* (i/o) Q0 : pointer to exponent */
+);
+
+Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e);
+
+Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e);
+
+#ifdef ENABLE_HR_MODE
+Word32 invFixp(Word32 op_m, Word16 *op_e);
+#endif
+
+#define BASOP_CFFT_MAX_LENGTH 480
+void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 sizeOfFft, Word16 s, Word16 *scale, Word32 *x);
+void BASOP_rfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
+void BASOP_irfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer);
+
+#if WMOPS
+extern BASIC_OP multiCounter[MAXCOUNTERS];
+extern int currCounter;
+#endif
+
+static __inline void basop_memcpy(void *dst, const void *src, size_t n)
+{
+#if WMOPS
+ multiCounter[currCounter].move16 += (UWord32)n / 2;
+#endif
+ /* check for overlapping memory */
+ assert((const char *)src + n <= (char *)dst || (char *)dst + n <= (const char *)src);
+ memcpy(dst, src, n);
+}
+
+static __inline void basop_memmove(void *dst, const void *src, size_t n)
+{
+#if WMOPS
+ multiCounter[currCounter].move16 += (UWord32)n / 2;
+#endif
+ memmove(dst, src, n);
+}
+
+static __inline void basop_memset(void *dst, int val, size_t n)
+{
+#if WMOPS
+ multiCounter[currCounter].move16 += (UWord32)n / 2;
+#endif
+ memset(dst, val, n);
+}
+
+/* Macros around Dyn_Mem that don't require duplicate declarations. */
+#ifdef DYNMEM_COUNT
+/* older visual studio doesn't have __func__ */
+#if defined _MSC_VER && _MSC_VER < 1900
+#define __func__ __FUNCTION__
+#endif
+#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ Dyn_Mem_In(__func__, sizeof(struct {__VA_ARGS__}))
+#define Dyn_Mem_Deluxe_Out() Dyn_Mem_Out()
+#else
+#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__
+#define Dyn_Mem_Deluxe_Out()
+#endif
+
+/* Macros missing from IVAS BASOP, used only in LC3plus */
+#define L_shl_pos(x, y) (L_shl((x), (y)))
+#define L_shr_pos(x, y) (L_shr((x), (y)))
+#define L_shr_pos_pos(x, y) (L_shr((x), (y)))
+
+#define L_shr_r_pos(x, shift) (L_shr_r(x, shift))
+
+#define shl_pos(x, y) (shl((x), (y)))
+#define shr_pos(x, y) (shr((x), (y)))
+#define shr_pos_pos(x, y) (shr((x), (y)))
+
+#define lshl_pos(x, y) (lshl(x, y))
+#define UL_lshr_pos(x, y) (UL_lshr(x, y))
+#define UL_lshl_pos(x, y) (UL_lshl(x, y))
+#endif /* __BASOP_UTIL_LC3PLUS_H__ */
diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c
new file mode 100644
index 0000000000000000000000000000000000000000..c13c4e49eb51759a9e74157cfd59d06e3c99cd96
--- /dev/null
+++ b/lib_lc3plus/constants.c
@@ -0,0 +1,5046 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "basop_util_lc3plus.h"
+#include "constants.h"
+#include "defines.h"
+
+#ifdef ENABLE_HR_MODE
+
+#ifdef CR8_G_ADD_75MS
+const Word32 LowDelayShapes_n960_N480_HRA_7_5ms_IP[720] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 87, 348, 823, 1614, 2855, 4711,
+ 7394, 11166, 16346, 23325, 32567, 44630, 60168, 79951, 104871,
+ 135960, 174404, 221554, 278944, 348306, 431580, 530938, 648792, 787807,
+ 950923, 1141360, 1362631, 1618557, 1913273, 2251235, 2637225, 3076358, 3574079,
+ 4136163, 4768712, 5478142, 6271180, 7154844, 8136428, 9223482, 10423785, 11745317,
+ 13196231, 14784811, 16519438, 18408546, 20460576, 22683925, 25086898, 27677652, 30464139,
+ 33454048, 36654744, 40073208, 43715977, 47589078, 51697972, 56047490, 60641775, 65484225,
+ 70577443, 75923181, 81522294, 87374702, 93479345, 99834159, 106436041, 113280836, 120363317,
+ 127677184, 135215062, 142968508, 150928157, 159083617, 167423428, 175935264, 184605929, 193421420,
+ 202366999, 211427267, 220586253, 229827503, 239134176, 248489151, 257875132, 267274759, 276670727,
+ 286045896, 295383416, 304666842, 313880253, 323008369, 332036665, 340951481, 349740127, 358390986,
+ 366893607, 375238791, 383418672, 391426786, 399258131, 406909219, 414378115, 421664463, 428769507,
+ 435696092, 442448656, 449033209, 455457302, 461729975, 467861704, 473864325, 479750954, 485535888,
+ 491234502, 496863130, 502438943, 507979811, 513504165, 519030849, 524578969, 530167737, 535816319,
+ 541543674, 547368406, 553308608, 559381722, 565604392, 571992342, 578560249, 585321630, 592288748,
+ 599472521, 606882448, 614526549, 622411321, 630541701, 638921050, 647551149, 656432204, 665562870,
+ 674940281, 684560092, 694416534, 704502476, 714809492, 725327938, 736047035, 746954953, 758038900,
+ 769285219, 780679474, 792206554, 803850758, 815595897, 827425384, 839322323, 851269604, 863249984,
+ 875246176, 887240926, 899217093, 911157723, 923046119, 934865908, 946601106, 958236175, 969756079,
+ 981146337, 992393068, 1003483035, 1014403685, 1025143183, 1035690443, 1046035156, 1056167806, 1066079698,
+ 1075762962, 1085210568, 1094416328, 1103374896, 1112081767, 1120533266, 1128726537, 1136659525, 1144330955,
+ 1151740310, 1158887799, 1165774327, 1172401460, 1178771388, 1184886881, 1190751250, 1196368299, 1201742283,
+ 1206877859, 1211780040, 1216454151, 1220905777, 1225140726, 1229164983, 1232984668, 1236606003, 1240035271,
+ 1243278790, 1246342881, 1249233843, 1251957932, 1254521342, 1256930191, 1259190506, 1261308214, 1263289136,
+ 1265138979, 1266863333, 1268467669, 1269957337, 1271337562, 1272613448, 1273789972, 1274871989, 1275864224,
+ 1276771276, 1277597614, 1278347576, 1279025364, 1279635046, 1280180548, 1280665658, 1281094017, 1281469123,
+ 1281794327, 1282072831, 1282307692, 1282501820, 1282657982, 1282778803, 1282866770, 1282924240, 1282953439,
+ 1282956475, 1282935340, 1282891922, 1282828007, 1282745290, 1282645385, 1282529830, 1282400095, 1282257591,
+ 1282103675, 1281939658, 1281766811, 1281586369, 1281399536, 1281207489, 1281011380, 1280812338, 1280611471,
+ 1280409867, 1280208592, 1280008692, 1279811190, 1279617083, 1279427343, 1279242908, 1279064691, 1278893575,
+ 1278730391, 1278575934, 1278430953, 1278296152, 1278172183, 1278059646, 1277959085, 1277870984, 1277795766,
+ 1277733793, 1277685360, 1277650698, 1277629970, 1277623272, 1277630630, 1277652006, 1277687290, 1277736307,
+ 1277798815, 1277874509, 1277963018, 1278063911, 1278176696, 1278300826, 1278435697, 1278580655, 1278734998,
+ 1278897977, 1279068803, 1279246650, 1279430656, 1279619930, 1279813555, 1280010596, 1280210097, 1280411091,
+ 1280612606, 1280813664, 1281013290, 1281210515, 1281404382, 1281593947, 1281778291, 1281956514, 1282127749,
+ 1282291161, 1282445951, 1282591364, 1282726688, 1282851259, 1282964467, 1283065755, 1283154623, 1283230634,
+ 1283293412, 1283342644, 1283378085, 1283399556, 1283406948, 1283400219, 1283379398, 1283344582, 1283295937,
+ 1283233697, 1283158163, 1283069704, 1282968748, 1282855789, 1282731378, 1282596123, 1282450686, 1282295780,
+ 1282132162, 1281960636, 1281782040, 1281597253, 1281407178, 1281212748, 1281014916, 1280814653, 1280612938,
+ -1280410760, -1280209108, -1280008970, -1279811325, -1279617137, -1279427356, -1279242908, -1279064691, -1278893575,
+ -1278730391, -1278575934, -1278430953, -1278296152, -1278172183, -1278059646, -1277959085, -1277870984, -1277795766,
+ -1277733793, -1277685360, -1277650698, -1277629970, -1277623272, -1277630630, -1277652006, -1277687290, -1277736307,
+ -1277798815, -1277874509, -1277963018, -1278063911, -1278176696, -1278300826, -1278435697, -1278580655, -1278734998,
+ -1278897977, -1279068803, -1279246650, -1279430656, -1279619930, -1279813555, -1280010596, -1280210097, -1280411091,
+ -1280612606, -1280813664, -1281013290, -1281210515, -1281404382, -1281593947, -1281778291, -1281956514, -1282127749,
+ -1282291161, -1282445951, -1282591364, -1282726688, -1282851259, -1282964467, -1283065755, -1283154623, -1283230634,
+ -1283293412, -1283342644, -1283378085, -1283399556, -1283406948, -1283400219, -1283379398, -1283344582, -1283295937,
+ -1283233697, -1283158163, -1283069704, -1282968748, -1282855789, -1282731378, -1282596123, -1282450686, -1282295780,
+ -1282132162, -1281960636, -1281782040, -1281597240, -1281407124, -1281212613, -1281014638, -1280814136, -1280612044,
+ -1280409293, -1280206794, -1280005436, -1279806071, -1279609505, -1279416489, -1279227704, -1279043754, -1278865148,
+ -1278692290, -1278525466, -1278364827, -1278210380, -1278061967, -1277919259, -1277781732, -1277648661, -1277519103,
+ -1277391882, -1277265579, -1277138516, -1277008749, -1276874050, -1276731906, -1276579498, -1276413701, -1276231074,
+ -1276027848, -1275799922, -1275542858, -1275251868, -1274921816, -1274547202, -1274122161, -1273640454, -1273095459,
+ -1272480163, -1271787153, -1271008605, -1270136275, -1269161491, -1268075138, -1266867650, -1265529002, -1264048705,
+ -1262415795, -1260618834, -1258645914, -1256484654, -1254122219, -1251545330, -1248740288, -1245693001, -1242389021,
+ -1238813588, -1234951678, -1230788064, -1226307382, -1221494200, -1216333106, -1210808785, -1204906119, -1198610276,
+ -1191906816, -1184781789, -1177221841, -1169214319, -1160747375, -1151810067, -1142392460, -1132485722, -1122082216,
+ -1111175584, -1099760832, -1087834398, -1075394224, -1062439811, -1048972272, -1034994376, -1020510578, -1005527053,
+ -990051705, -974094182, -957665874, -940779904, -923451116, -905696046, -887532891, -868981469, -850063169,
+ -830800896, -811219007, -791343239, -771200631, -750819438, -730229039, -709459838, -688543157, -667511126,
+ -646396563, -625232849, -604053802, -582893543, -561786350, -540766526, -519868245, -499125406, -478571481,
+ -458239366, -438161227, -418368350, -398890991, -379758233, -360997846, -342636148, -324697881, -307206093,
+ -290182024, -273645013, -257612410, -242099504, -227119464, -212683299, -198799827, -185475666, -172715241,
+ -160520802, -148892465, -137828265, -127324223, -117374432, -107971150, -99104909, -90764635, -82937772,
+ -75610419, -68767471, -62392760, -56469205, -50978959, -45903556, -41224052, -36921169, -32975429,
+ -29367284, -26077235, -23085950, -20374365, -17923784, -15715959, -13733175, -11958308, -10374886,
+ -8967135, -7720017, -6619257, -5651362, -4803637, -4064184, -3421902, -2866477, -2388368,
+ -1978789, -1629681, -1333688, -1084125, -874947, -700710, -556540, -438092, -341515,
+ -263414, -200812, -151118, -112086, -81786, -58572, -41046, -28035, -18564,
+ -11827, -7166, -4052, -2065, -873, -219, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+const Word32 LowDelayShapes_n960_N960_HRA_7_5ms_IP[1440] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 44, 108, 200,
+ 327, 496, 716, 997, 1352, 1793, 2334, 2993, 3788,
+ 4740, 5873, 7210, 8782, 10618, 12754, 15228, 18079, 21354,
+ 25102, 29375, 34232, 39736, 45954, 52960, 60833, 69657, 79523,
+ 90531, 102783, 116393, 131479, 148170, 166600, 186913, 209263, 233812,
+ 260731, 290202, 322417, 357578, 395898, 437601, 482924, 532113, 585429,
+ 643144, 705541, 772919, 845587, 923872, 1008108, 1098650, 1195861, 1300121,
+ 1411824, 1531379, 1659208, 1795748, 1941453, 2096787, 2262233, 2438287, 2625458,
+ 2824273, 3035270, 3259002, 3496037, 3746956, 4012353, 4292837, 4589026, 4901555,
+ 5231067, 5578220, 5943680, 6328125, 6732242, 7156730, 7602292, 8069643, 8559503,
+ 9072598, 9609661, 10171429, 10758643, 11372046, 12012385, 12680404, 13376850, 14102468,
+ 14858000, 15644185, 16461757, 17311444, 18193967, 19110038, 20060361, 21045626, 22066514,
+ 23123691, 24217808, 25349499, 26519382, 27728053, 28976092, 30264055, 31592472, 32961855,
+ 34372684, 35825415, 37320475, 38858262, 40439142, 42063449, 43731482, 45443509, 47199758,
+ 49000423, 50845659, 52735581, 54670266, 56649748, 58674020, 60743031, 62856690, 65014857,
+ 67217351, 69463943, 71754359, 74088280, 76465337, 78885116, 81347157, 83850949, 86395935,
+ 88981513, 91607029, 94271785, 96975035, 99715986, 102493800, 105307656, 108156591, 111039641,
+ 113955799, 116904014, 119883198, 122892222, 125929920, 128995090, 132086493, 135202860, 138342888,
+ 141505243, 144688567, 147891470, 151112543, 154350350, 157603439, 160870336, 164149553, 167439589,
+ 170738931, 174046055, 177359434, 180677535, 183998823, 187321766, 190644834, 193966503, 197285258,
+ 200599596, 203908028, 207209080, 210501300, 213783255, 217053539, 220310770, 223553598, 226780705,
+ 229990806, 233182654, 236355043, 239506805, 242636819, 245744010, 248827351, 251885864, 254918626,
+ 257924767, 260903473, 263853991, 266775622, 269667734, 272529755, 275361176, 278161556, 280930518,
+ 283667753, 286373022, 289046153, 291687043, 294295661, 296872047, 299416309, 301928628, 304409254,
+ 306858511, 309276789, 311664551, 314022327, 316350717, 318650389, 320922075, 323166575, 325384751,
+ 327577531, 329745900, 331890905, 334013649, 336115291, 338197045, 340260173, 342305990, 344335852,
+ 346351165, 348353370, 350343952, 352324427, 354296346, 356261288, 358220860, 360176691, 362130431,
+ 364083745, 366038312, 367995821, 369957968, 371926451, 373902968, 375889214, 377886876, 379897629,
+ 381923135, 383965040, 386024966, 388104513, 390205254, 392328729, 394476448, 396649881, 398850460,
+ 401079575, 403338572, 405628746, 407951345, 410307564, 412698544, 415125367, 417589059, 420090585,
+ 422630847, 425210685, 427830873, 430492120, 433195067, 435940288, 438728287, 441559502, 444434298,
+ 447352971, 450315749, 453322788, 456374176, 459469929, 462609996, 465794259, 469022529, 472294553,
+ 475610011, 478968518, 482369626, 485812825, 489297542, 492823148, 496388953, 499994212, 503638125,
+ 507319839, 511038449, 514793004, 518582502, 522405897, 526262100, 530149980, 534068367, 538016053,
+ 541991796, 545994319, 550022317, 554074452, 558149362, 562245659, 566361935, 570496756, 574648675,
+ 578816224, 582997925, 587192283, 591397795, 595612950, 599836228, 604066106, 608301058, 612539556,
+ 616780072, 621021084, 625261070, 629498515, 633731914, 637959769, 642180591, 646392905, 650595252,
+ 654786183, 658964269, 663128098, 667276277, 671407434, 675520217, 679613298, 683685373, 687735163,
+ 691761414, 695762900, 699738424, 703686816, 707606936, 711497676, 715357958, 719186737, 722983000,
+ 726745768, 730474096, 734167073, 737823824, 741443507, 745025319, 748568492, 752072293, 755536028,
+ 758959039, 762340704, 765680440, 768977700, 772231975, 775442794, 778609720, 781732356, 784810341,
+ 787843351, 790831096, 793773326, 796669823, 799520406, 802324927, 805083276, 807795372, 810461171,
+ 813080658, 815653853, 818180806, 820661596, 823096332, 825485155, 827828229, 830125749, 832377934,
+ 834585028, 836747302, 838865047, 840938578, 842968232, 844954366, 846897354, 848797592, 850655491,
+ 852471478, 854245997, 855979505, 857672472, 859325380, 860938723, 862513004, 864048738, 865546444,
+ 867006653, 868429898, 869816720, 871167666, 872483283, 873764126, 875010749, 876223709, 877403563,
+ 878550870, 879666189, 880750077, 881803089, 882825781, 883818705, 884782410, 885717445, 886624352,
+ 887503671, 888355939, 889181688, 889981445, 890755734, 891505074, 892229977, 892930955, 893608509,
+ 894263138, 894895337, 895505593, 896094389, 896662203, 897209507, 897736768, 898244447, 898733000,
+ 899202877, 899654523, 900088379, 900504877, 900904447, 901287510, 901654485, 902005783, 902341811,
+ 902662967, 902969647, 903262240, 903541129, 903806691, 904059297, 904299312, 904527095, 904742999,
+ 904947372, 905140554, 905322879, 905494676, 905656265, 905807964, 905950080, 906082916, 906206768,
+ 906321926, 906428673, 906527284, 906618032, 906701178, 906776980, 906845690, 906907551, 906962802,
+ 907011675, 907054396, 907091185, 907122257, 907147818, 907168073, 907183217, 907193443, 907198938,
+ 907199882, 907196451, 907188818, 907177150, 907161608, 907142351, 907119533, 907093305, 907063813,
+ 907031199, 906995603, 906957162, 906916008, 906872273, 906826083, 906777563, 906726837, 906674025,
+ 906619245, 906562613, 906504244, 906444251, 906382745, 906319835, 906255629, 906190236, 906123759,
+ 906056304, 905987975, 905918873, 905849099, 905778755, 905707939, 905636751, 905565287, 905493644,
+ 905421918, 905350204, 905278596, 905207187, 905136068, 905065331, 904995065, 904925359, 904856301,
+ 904787977, 904720472, 904653870, 904588254, 904523701, 904460295, 904398114, 904337234, 904277728,
+ 904219670, 904163129, 904108175, 904054874, 904003290, 903953487, 903905525, 903859462, 903815353,
+ 903773252, 903733209, 903695274, 903659492, 903625906, 903594557, 903565482, 903538716, 903514291,
+ 903492237, 903472579, 903455342, 903440546, 903428208, 903418343, 903410963, 903406076, 903403687,
+ 903403799, 903406411, 903411521, 903419121, 903429201, 903441750, 903456751, 903474186, 903494033,
+ 903516269, 903540866, 903567793, 903597018, 903628506, 903662217, 903698112, 903736145, 903776272,
+ 903818442, 903862605, 903908708, 903956694, 904006505, 904058081, 904111359, 904166274, 904222761,
+ 904280750, 904340172, 904400953, 904463022, 904526303, 904590718, 904656191, 904722641, 904789988,
+ 904858152, 904927048, 904996594, 905066706, 905137298, 905208286, 905279583, 905351102, 905422757,
+ 905494462, 905566128, 905637670, 905709001, 905780033, 905850681, 905920859, 905990482, 906059464,
+ 906127723, 906195175, 906261739, 906327332, 906391876, 906455291, 906517501, 906578429, 906638002,
+ 906696146, 906752790, 906807866, 906861306, 906913045, 906963019, 907011167, 907057430, 907101752,
+ 907144078, 907184355, 907222535, 907258571, 907292418, 907324034, 907353381, 907380422, 907405124,
+ 907427456, 907447391, 907464903, 907479970, 907492575, 907502701, 907510335, 907515468, 907518092,
+ 907518205, 907515805, 907510896, 907503482, 907493572, 907481179, 907466317, 907449004, 907429261,
+ 907407111, 907382581, 907355702, 907326506, 907295028, 907261307, 907225384, 907187302, 907147109,
+ 907104853, 907060585, 907014361, 906966236, 906916270, 906864523, 906811060, 906755944, 906699245,
+ 906641031, 906581374, 906520347, 906458025, 906394483, 906329801, 906264057, 906197332, 906129707,
+ 906061266, 905992093, 905922271, 905851888, 905781028, 905709780, 905638230, 905566465, 905494574,
+ -905422645, -905350765, -905279024, -905207507, -905136304, -905065500, -904995184, -904925439, -904856352,
+ -904788008, -904720488, -904653877, -904588254, -904523701, -904460295, -904398114, -904337234, -904277728,
+ -904219670, -904163129, -904108175, -904054874, -904003290, -903953487, -903905525, -903859462, -903815353,
+ -903773252, -903733209, -903695274, -903659492, -903625906, -903594557, -903565482, -903538716, -903514291,
+ -903492237, -903472579, -903455342, -903440546, -903428208, -903418343, -903410963, -903406076, -903403687,
+ -903403799, -903406411, -903411521, -903419121, -903429201, -903441750, -903456751, -903474186, -903494033,
+ -903516269, -903540866, -903567793, -903597018, -903628506, -903662217, -903698112, -903736145, -903776272,
+ -903818442, -903862605, -903908708, -903956694, -904006505, -904058081, -904111359, -904166274, -904222761,
+ -904280750, -904340172, -904400953, -904463022, -904526303, -904590718, -904656191, -904722641, -904789988,
+ -904858152, -904927048, -904996594, -905066706, -905137298, -905208286, -905279583, -905351102, -905422757,
+ -905494462, -905566128, -905637670, -905709001, -905780033, -905850681, -905920859, -905990482, -906059464,
+ -906127723, -906195175, -906261739, -906327332, -906391876, -906455291, -906517501, -906578429, -906638002,
+ -906696146, -906752790, -906807866, -906861306, -906913045, -906963019, -907011167, -907057430, -907101752,
+ -907144078, -907184355, -907222535, -907258571, -907292418, -907324034, -907353381, -907380422, -907405124,
+ -907427456, -907447391, -907464903, -907479970, -907492575, -907502701, -907510335, -907515468, -907518092,
+ -907518205, -907515805, -907510896, -907503482, -907493572, -907481179, -907466317, -907449004, -907429261,
+ -907407111, -907382581, -907355702, -907326506, -907295028, -907261307, -907225384, -907187302, -907147109,
+ -907104853, -907060585, -907014361, -906966236, -906916270, -906864523, -906811060, -906755944, -906699245,
+ -906641031, -906581374, -906520347, -906458025, -906394483, -906329801, -906264050, -906197315, -906129676,
+ -906061214, -905992012, -905922152, -905851718, -905780792, -905709459, -905637802, -905565904, -905493847,
+ -905421715, -905349587, -905277545, -905205668, -905134032, -905062714, -904991788, -904921326, -904851397,
+ -904782068, -904713403, -904645463, -904578305, -904511983, -904446548, -904382044, -904318513, -904255990,
+ -904194508, -904134091, -904074760, -904016528, -903959404, -903903387, -903848473, -903794647, -903741889,
+ -903690170, -903639452, -903589690, -903540829, -903492806, -903445546, -903398968, -903352977, -903307470,
+ -903262332, -903217440, -903172655, -903127830, -903082805, -903037408, -902991455, -902944749, -902897082,
+ -902848230, -902797958, -902746017, -902692145, -902636065, -902577487, -902516107, -902451605, -902383649,
+ -902311891, -902235969, -902155504, -902070104, -901979361, -901882852, -901780138, -901670764, -901554261,
+ -901430141, -901297903, -901157028, -901006979, -900847206, -900677140, -900496195, -900303767, -900099237,
+ -899881968, -899651302, -899406566, -899147069, -898872099, -898580929, -898272809, -897946972, -897602633,
+ -897238985, -896855201, -896450436, -896023825, -895574479, -895101492, -894603937, -894080864, -893531305,
+ -892954268, -892348742, -891713696, -891048075, -890350805, -889620793, -888856922, -888058059, -887223048,
+ -886350714, -885439866, -884489291, -883497761, -882464029, -881386834, -880264898, -879096929, -877881622,
+ -876617661, -875303716, -873938450, -872520516, -871048562, -869521229, -867937155, -866294976, -864593328,
+ -862830848, -861006177, -859117961, -857164854, -855145521, -853058635, -850902887, -848676980, -846379640,
+ -844009611, -841565658, -839046575, -836451182, -833778329, -831026896, -828195801, -825283996, -822290474,
+ -819214267, -816054453, -812810153, -809480538, -806064827, -802562292, -798972258, -795294106, -791527275,
+ -787671264, -783725629, -779689995, -775564045, -771347531, -767040273, -762642156, -758153138, -753573244,
+ -748902575, -744141301, -739289667, -734347993, -729316674, -724196178, -718987051, -713689917, -708305473,
+ -702834496, -697277838, -691636430, -685911277, -680103464, -674214150, -668244572, -662196041, -656069944,
+ -649867743, -643590972, -637241240, -630820227, -624329685, -617771433, -611147363, -604459432, -597709664,
+ -590900148, -584033037, -577110543, -570134942, -563108566, -556033804, -548913099, -541748950, -534543903,
+ -527300554, -520021545, -512709564, -505367338, -497997635, -490603260, -483187052, -475751882, -468300650,
+ -460836282, -453361728, -445879958, -438393963, -430906743, -423421316, -415940704, -408467938, -401006049,
+ -393558069, -386127025, -378715938, -371327818, -363965660, -356632445, -349331130, -342064650, -334835913,
+ -327647796, -320503142, -313404758, -306355410, -299357818, -292414658, -285528555, -278702079, -271937746,
+ -265238010, -258605264, -252041836, -245549983, -239131895, -232789684, -226525389, -220340970, -214238305,
+ -208219189, -202285333, -196438360, -190679806, -185011113, -179433635, -173948631, -168557267, -163260612,
+ -158059640, -152955229, -147948160, -143039115, -138228681, -133517347, -128905505, -124393450, -119981382,
+ -115669406, -111457534, -107345683, -103333681, -99421264, -95608082, -91893698, -88277589, -84759152,
+ -81337704, -78012482, -74782650, -71647299, -68605451, -65656059, -62798015, -60030148, -57351228,
+ -54759972, -52255046, -49835065, -47498599, -45244179, -43070293, -40975397, -38957912, -37016231,
+ -35148723, -33353731, -31629581, -29974582, -28387030, -26865208, -25407397, -24011868, -22676893,
+ -21400745, -20181701, -19018041, -17908057, -16850050, -15842335, -14883242, -13971116, -13104325,
+ -12281255, -11500315, -10759938, -10058585, -9394741, -8766919, -8173665, -7613552, -7085185,
+ -6587202, -6118273, -5677102, -5262427, -4873021, -4507690, -4165278, -3844660, -3544752,
+ -3264499, -3002887, -2758933, -2531691, -2320249, -2123731, -1941292, -1772123, -1615446,
+ -1470519, -1336627, -1213092, -1099261, -994515, -898263, -809943, -729021, -654988,
+ -587365, -525695, -469547, -418515, -372215, -330284, -292383, -258192, -227410,
+ -199757, -174969, -152801, -133024, -115424, -99803, -85978, -73777, -63042,
+ -53629, -45403, -38240, -32028, -26663, -22051, -18104, -14745, -11902,
+ -9511, -7514, -5860, -4500, -3394, -2503, -1797, -1244, -820,
+ -502, -271, -109, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0};
+#endif /* #ifdef CR8_G_ADD_75MS */
+
+RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_2_5ms_IP[240] = {
+ 214, 1407, 4144, 9592, 19434, 36052, 62711, 103783, 164992,
+ 253687, 379148, 552904, 789076, 1104722, 1520198, 2059494, 2750561, 3625602,
+ 4721314, 6079061, 7744972, 9769942, 12209518, 15123669, 18576419, 22635352, 27370973,
+ 32855950, 39164229, 46370051, 54546874, 63766241, 74096597, 85602085, 98341344, 112366317,
+ 127721101, 144440829, 162550610, 182064542, 202984778, 225300694, 248988134, 274008783, 300309659,
+ 327822776, 356464985, 386138051, 416728983, 448110659, 480142780, 512673177, 545539472, 578571104,
+ 611591694, 644421704, 676881340, 708793602, 739987407, 770300656, 799583149, 827699226, 854530045,
+ 879975405, 903955057, 926409465, 947300009, 966608644, 984337071, 1000505451, 1015150768, 1028324899,
+ 1040092491, 1050528715, 1059716983, 1067746699, 1074711082, 1080705143, 1085823820, 1090160324, 1093804700,
+ 1096842623, 1099354431, 1101414399, 1103090233, 1104442796, 1105526028, 1106387052, 1107066439, 1107598605,
+ 1108012308, 1108331223, 1108574556, 1108757676, 1108892731, 1108989242, 1109054637, 1109094735, 1109114155,
+ 1109116652, 1109105394, 1109083163, 1109052498, 1109015788, 1108975323, 1108933307, 1108891843, 1108852902,
+ 1108818280, 1108789546, 1108767992, 1108754591, 1108749953, 1108754306, 1108767481, 1108788919, 1108817694,
+ 1108852552, 1108891964, 1108934195, -1108977380, -1109019614, -1109059032, -1109093898, -1109122681, -1109144125,
+ -1109157302, -1109161650, -1109156995, -1109143556, -1109121925, -1109093037, -1109058122, -1109018637, -1108976187,
+ -1108932433, -1108888980, -1108847255, -1108808366, -1108772946, -1108740971, -1108711558, -1108682731, -1108651158,
+ -1108611855, -1108557851, -1108479820, -1108365676, -1108200143, -1107964292, -1107635083, -1107184891, -1106581062,
+ -1105785503, -1104754330, -1103437601, -1101779148, -1099716548, -1097181229, -1094098763, -1090389339, -1085968441,
+ -1080747748, -1074636248, -1067541577, -1059371579, -1050036059, -1039448713, -1027529209, -1014205354, -999415302,
+ -983109740, -965253961, -945829756, -924837032, -902295070, -878243367, -852741971, -825871301, -797731403,
+ -768440669, -738134051, -706960817, -675081952, -642667284, -609892453, -576935833, -543975515, -511186440,
+ -478737764, -446790521, -415495622, -384992199, -355406317, -326850029, -299420751, -273200929, -248257970,
+ -224644391, -202398148, -181543141, -162089834, -144035993, -127367520, -112059369, -98076525, -85375063,
+ -73903244, -63602666, -54409446, -46255413, -39069306, -32777951, -27307388, -22583946, -18535216,
+ -15090941, -12183768, -9749883, -7729511, -6067277, -4712439, -3619003, -2745721, -2055997,
+ -1517713, -1102987, -787888, -552109, -378629, -253358, -164789, -103664, -62644,
+ -36017, -19417, -9584, -4141, -1406, -214 };
+RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_5ms_IP[420] = {
+ 153, 1006, 2962, 6854, 13880, 25735, 44738, 73986, 117524,
+ 180533, 269534, 392603, 559593, 782368, 1075031, 1454143, 1938937, 2551502,
+ 3316947, 4263524, 5422707, 6829222, 8521011, 10539137, 12927604, 15733109, 19004698,
+ 22793344, 27151431, 32132152, 37788816, 44174082, 51339114, 59332667, 68200136, 77982547,
+ 88715548, 100428385, 113142910, 126872625, 141621804, 157384706, 174144915, 191874817, 210535261,
+ 230075406, 250432778, 271533559, 293293106, 315616716, 338400617, 361533198, 384896437, 408367524,
+ 431820627, 455128780, 478165843, 500808481, 522938120, 544442827, 565219197, 585174124, 604225689,
+ 622304754, 639355717, 655337129, 670221993, 683997778, 696666136, 708242355, 718754575, 728242788,
+ 736757688, 744359378, 751116012, 757102394, 762398585, 767088551, 771258886, 774997644, 778393288,
+ 781533768, 784505744, 787393944, 790280637, 793245232, 796363956, 799709608, 803351363, 807354601,
+ 811780739, 816687064, 822126537, 828147569, 834793773, 842103681, 850110443, 858841520, 868318369,
+ 878556163, 889563529, 901342346, 913887605, 927187338, 941222645, 955967800, 971390453, 987451937,
+ 1004107649, 1021307531, 1038996616, 1057115651, 1075601769, 1094389201, 1113410024, 1132594917, 1151873921,
+ 1171177186, 1190435688, 1209581916, 1228550504, 1247278803, 1265707395, 1283780533, 1301446498, 1318657893,
+ 1335371854, 1351550191, 1367159457, 1382170967, 1396560748, 1410309460, 1423402271, 1435828702, 1447582463,
+ 1458661263, 1469066617, 1478803649, 1487880888, 1496310057, 1504105864, 1511285781, 1517869810, 1523880240,
+ 1529341392, 1534279342, 1538721639, 1542697001, 1546235012, 1549365809, 1552119778, 1554527246, 1556618203,
+ 1558422028, 1559967247, 1561281317, 1562390436, 1563319395, 1564091445, 1564728213, 1565249633, 1565673917,
+ 1566017543, 1566295272, 1566520181, 1566703721, 1566855785, 1566984788, 1567097770, 1567200488, 1567297538,
+ 1567392456, 1567487845, 1567585484, 1567686442, 1567791191, 1567899701, 1568011546, 1568125984, 1568242042,
+ 1568358534, 1568474289, 1568587995, 1568698311, 1568803945, 1568903672, 1568996349, 1569080932, 1569156484,
+ 1569222192, 1569277370, 1569321465, 1569354064, 1569374893, 1569383815, 1569380829, 1569366065, 1569339781,
+ 1569302349, 1569254257, 1569196093, 1569128539, 1569052361, 1568968403, 1568877571, 1568780830, 1568679193,
+ 1568573710, 1568465461, 1568355548, 1568245083, 1568135185, 1568026967, 1567921528, 1567819946, 1567723271,
+ 1567632511, 1567548628, 1567472527, 1567405047, 1567346952, 1567298919, 1567261537, 1567235287, 1567220544,
+ 1567217562, 1567226472, 1567247272, 1567279829, 1567323868, 1567378978, 1567444612, 1567520086, 1567604589,
+ 1567697189, 1567796846, 1567902419, 1568012687, 1568126359, 1568242097, -1568358534, -1568474289, -1568587995,
+ -1568698311, -1568803945, -1568903672, -1568996349, -1569080932, -1569156484, -1569222192, -1569277370, -1569321465,
+ -1569354064, -1569374893, -1569383815, -1569380829, -1569366065, -1569339781, -1569302349, -1569254257, -1569196093,
+ -1569128539, -1569052361, -1568968403, -1568877571, -1568780830, -1568679193, -1568573710, -1568465461, -1568355548,
+ -1568245083, -1568135185, -1568026967, -1567921528, -1567819946, -1567723271, -1567632511, -1567548628, -1567472527,
+ -1567405047, -1567346952, -1567298919, -1567261537, -1567235287, -1567220544, -1567217562, -1567226472, -1567247272,
+ -1567279829, -1567323868, -1567378978, -1567444612, -1567520086, -1567604589, -1567697189, -1567796846, -1567902419,
+ -1568012687, -1568126359, -1568242097, -1568358479, -1568473914, -1568586854, -1568695591, -1568798286, -1568892916,
+ -1568977226, -1569048656, -1569104263, -1569140635, -1569153790, -1569139071, -1569091028, -1569003308, -1568868529,
+ -1568678156, -1568422382, -1568089999, -1567668277, -1567142834, -1566497514, -1565714254, -1564772952, -1563651331,
+ -1562324794, -1560766278, -1558946098, -1556831792, -1554387964, -1551576132, -1548354584, -1544678268, -1540498696,
+ -1535763912, -1530418507, -1524403718, -1517657618, -1510115411, -1501709847, -1492371764, -1482030768, -1470616033,
+ -1458057247, -1444285654, -1429235205, -1412843785, -1395054486, -1375816907, -1355088440, -1332835519, -1309034797,
+ -1283674224, -1256753995, -1228287351, -1198301206, -1166836586, -1133948872, -1099707826, -1064197417, -1027515419,
+ -989772809, -951092956, -911610610, -871470715, -830827045, -789840682, -748678366, -707510713, -666510349,
+ -625849956, -585700281, -546228117, -507594292, -469951710, -433443460, -398201053, -364342807, -331972440,
+ -301177891, -272030413, -244583969, -218874947, -194922208, -172727465, -152275991, -133537623, -116468025,
+ -101010189, -87096098, -74648510, -63582812, -53808877, -45232880, -37759037, -31291209, -25734358,
+ -20995832, -16986455, -13621428, -10821035, -8511162, -6623645, -5096451, -3873717, -2905668,
+ -2148423, -1563717, -1118555, -784819, -538834, -360926, -234965, -147925, -89451,
+ -51458, -27754, -13704, -5923, -2011, -306 };
+RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_IP[780] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 105, 687, 2025, 4688, 9502, 17634,
+ 30689, 50817, 80838, 124375, 186009, 271432, 387623, 543017, 747676,
+ 1013467, 1354215, 1785853, 2326545, 2996777, 3819424, 4819763, 6025441, 7466392,
+ 9174686, 11184326, 13530961, 16251545, 19383921, 22966334, 27036891, 31632957, 36790505,
+ 42543426, 48922816, 55956247, 63667042, 72073568, 81188571, 91018551, 101563225, 112815065,
+ 124758945, 137371906, 150623045, 164473553, 178876885, 193779093, 209119296, 224830297, 240839344,
+ 257069006, 273438164, 289863100, 306258645, 322539389, 338620907, 354420979, 369860792, 384866072,
+ 399368244, 413305531, 426623420, 439275707, 451224957, 462442920, 472910759, 482619111, 491567983,
+ 499766479, 507232383, 513991603, 520077504, 525530145, 530395443, 534724296, 538571682, 541995756,
+ 545056975, 547817267, 550339253, 552685542, 554918106, 557097730, 559283544, 561532631, 563899693,
+ 566436780, 569193061, 572214618, 575544274, 579221418, 583281849, 587757606, 592676805, 598063482,
+ 603937430, 610314061, 617204279, 624614388, 632546030, 640996174, 649957147, 659416723, 669358259,
+ 679760895, 690599795, 701846444, 713468981, 725432569, 737699796, 750231092, 762985159, 775919415,
+ 788990419, 802154306, 815367198, 828585593, 841766740, 854868978, 867852045, 880677358, 893308258,
+ 905710214, 917851001, 929700832, 941232469, 952421292, 963245346, 973685357, 983724726, 993349512,
+ 1002548385, 1011312579, 1019635831, 1027514316, 1034946573, 1041933433, 1048477942, 1054585275, 1060262649,
+ 1065519228, 1070366010, 1074815711, 1078882625, 1082582470, 1085932219, 1088949913, 1091654462, 1094065430,
+ 1096202822, 1098086863, 1099737781, 1101175600, 1102419947, 1103489872, 1104403690, 1105178850, 1105831817,
+ 1106377989, 1106831632, 1107205842, 1107512525, 1107762397, 1107965009, 1108128778, 1108261042, 1108368118,
+ 1108455375, 1108527311, 1108587638, 1108639366, 1108684891, 1108726077, 1108764338, 1108800715, 1108835945,
+ 1108870522, 1108904754, 1108938811, 1108972723, 1109006542, 1109040205, 1109073607, 1109106645, 1109139216,
+ 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447, 1109346114, 1109371602, 1109395837,
+ 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552, 1109525430, 1109537663, 1109548227,
+ 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814, 1109574431, 1109571363, 1109566630,
+ 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879, 1109489374, 1109472496, 1109454299,
+ 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555, 1109294742, 1109268095, 1109240684,
+ 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121, 1109033354, 1109002402, 1108971338,
+ 1108940237, 1108909175, 1108878226, 1108847464, 1108816965, 1108786801, 1108757046, 1108727774, 1108699056,
+ 1108670963, 1108643567, 1108616936, 1108591139, 1108566243, 1108542312, 1108519412, 1108497603, 1108476946,
+ 1108457499, 1108439319, 1108422458, 1108406967, 1108392895, 1108380286, 1108369184, 1108359626, 1108351647,
+ 1108345281, 1108340553, 1108337489, 1108336107, 1108336422, 1108338446, 1108342183, 1108347636, 1108354799,
+ 1108363664, 1108374217, 1108386437, 1108400301, 1108415777, 1108432830, 1108451419, 1108471498, 1108493014,
+ 1108515912, 1108540129, 1108565598, 1108592247, 1108620001, 1108648779, 1108678497, 1108709066, 1108740395,
+ 1108772389, 1108804951, 1108837980, 1108871376, 1108905035, 1108938852, 1108972723, 1109006542, 1109040205,
+ 1109073607, 1109106645, 1109139216, 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447,
+ 1109346114, 1109371602, 1109395837, 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552,
+ 1109525430, 1109537663, 1109548227, 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814,
+ 1109574431, 1109571363, 1109566630, 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879,
+ 1109489374, 1109472496, 1109454299, 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555,
+ 1109294742, 1109268095, 1109240684, 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121,
+ 1109033354, 1109002402, 1108971338, -1108940237, -1108909175, -1108878226, -1108847464, -1108816965, -1108786801,
+ -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936, -1108591139, -1108566243, -1108542312,
+ -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458, -1108406967, -1108392895, -1108380286,
+ -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489, -1108336107, -1108336422, -1108338446,
+ -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437, -1108400301, -1108415777, -1108432830,
+ -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598, -1108592247, -1108620001, -1108648779,
+ -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980, -1108871376, -1108905035, -1108938852,
+ -1108972723, -1109006542, -1109040205, -1109073607, -1109106645, -1109139216, -1109171221, -1109202563, -1109233147,
+ -1109262880, -1109291675, -1109319447, -1109346114, -1109371602, -1109395837, -1109418753, -1109440288, -1109460385,
+ -1109478991, -1109496061, -1109511552, -1109525430, -1109537663, -1109548227, -1109557101, -1109564272, -1109569731,
+ -1109573473, -1109575498, -1109575814, -1109574431, -1109571363, -1109566630, -1109560257, -1109552270, -1109542702,
+ -1109531587, -1109518966, -1109504879, -1109489374, -1109472496, -1109454299, -1109434835, -1109414161, -1109392335,
+ -1109369417, -1109345469, -1109320555, -1109294742, -1109268095, -1109240684, -1109212578, -1109183848, -1109154564,
+ -1109124800, -1109094627, -1109064121, -1109033354, -1109002402, -1108971338, -1108940237, -1108909175, -1108878226,
+ -1108847464, -1108816965, -1108786801, -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936,
+ -1108591139, -1108566243, -1108542312, -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458,
+ -1108406967, -1108392895, -1108380286, -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489,
+ -1108336107, -1108336422, -1108338446, -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437,
+ -1108400301, -1108415777, -1108432830, -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598,
+ -1108592247, -1108620001, -1108648779, -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980,
+ -1108871376, -1108905035, -1108938852, -1108972682, -1109006261, -1109039351, -1109071571, -1109102407, -1109131162,
+ -1109156896, -1109178374, -1109193989, -1109201688, -1109198891, -1109182406, -1109148336, -1109091993, -1109007805,
+ -1108889225, -1108728643, -1108517302, -1108245211, -1107901063, -1107472158, -1106944320, -1106301824, -1105527310,
+ -1104601707, -1103504157, -1102211925, -1100700333, -1098942681, -1096910184, -1094571927, -1091894839, -1088843693,
+ -1085381150, -1081467851, -1077062556, -1072122362, -1066602975, -1060459071, -1053644721, -1046113898, -1037821043,
+ -1028721699, -1018773190, -1007935330, -996171157, -983447669, -969736537, -955014802, -939265519, -922478340,
+ -904650040, -885784954, -865895333, -845001612, -823132583, -800325469, -776625909, -752087844, -726773304,
+ -700752110, -674101477, -646905528, -619254721, -591245188, -562977986, -534558266, -506094363, -477696807,
+ -449477265, -421547413, -394017760, -366996430, -340587909, -314891801, -290001587, -266003441, -242975106,
+ -220984887, -200090776, -180339738, -161767200, -144396752, -128240072, -113297104, -99556455, -86996029,
+ -75583860, -65279122, -56033278, -47791333, -40493145, -34074759, -28469709, -23610284, -19428682,
+ -15858075, -12833534, -10292814, -8176993, -6430970, -5003818, -3849000, -2924474, -2192679,
+ -1620441, -1178790, -842729, -590941, -405483, -271445, -176613, -111130, -67168,
+ -38622, -20823, -10279, -4442, -1508, -229 };
+RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_2_5ms_IP[480] = {
+ 214, 718, 1564, 2887, 4850, 7655, 11549, 16828, 23847,
+ 33024, 44855, 59914, 78870, 102494, 131671, 167412, 210862, 263320,
+ 326247, 401279, 490246, 595184, 718349, 862234, 1029583, 1223409, 1447008,
+ 1703973, 1998212, 2333963, 2715805, 3148674, 3637878, 4189104, 4808432, 5502344,
+ 6277732, 7141903, 8102584, 9167924, 10346495, 11647288, 13079711, 14653577, 16379097,
+ 18266869, 20327854, 22573365, 25015043, 27664828, 30534935, 33637823, 36986159, 40592781,
+ 44470665, 48632874, 53092523, 57862728, 62956563, 68387004, 74166887, 80308851, 86825288,
+ 93728290, 101029595, 108740533, 116871978, 125434289, 134437259, 143890065, 153801219, 164178510,
+ 175028964, 186358792, 198173341, 210477054, 223273422, 236564945, 250353087, 264638241, 279419691,
+ 294695574, 310462852, 326717278, 343453367, 360664374, 378342268, 396477718, 415060072, 434077349,
+ 453516232, 473362064, 493598851, 514209273, 535174695, 556475190, 578089564, 599995393, 622169062,
+ 644585817, 667219821, 690044217, 713031208, 736152130, 759377547, 782677345, 806020840, 829376886,
+ 852713991, 876000447, 899204452, 922294246, 945238242, 968005170, 990564209, 1012885127, 1034938418,
+ 1056695435, 1078128516, 1099211112, 1119917901, 1140224902, 1160109567, 1179550884, 1198529445, 1217027528,
+ 1235029144, 1252520091, 1269487982, 1285922269, 1301814250, 1317157066, 1331945687, 1346176884, 1359849191,
+ 1372962859, 1385519797, 1397523511, 1408979025, 1419892807, 1430272680, 1440127732, 1449468226, 1458305498,
+ 1466651859, 1474520500, 1481925383, 1488881148, 1495403011, 1501506666, 1507208191, 1512523957, 1517470536,
+ 1522064619, 1526322933, 1530262165, 1533898889, 1537249499, 1540330149, 1543156689, 1545744622, 1548109049,
+ 1550264632, 1552225553, 1554005489, 1555617576, 1557074399, 1558387963, 1559569689, 1560630404, 1561580336,
+ 1562429115, 1563185777, 1563858772, 1564455973, 1564984695, 1565451702, 1565863235, 1566225027, 1566542325,
+ 1566819919, 1567062160, 1567272989, 1567455965, 1567614286, 1567750818, 1567868122, 1567968477, 1568053906,
+ 1568126199, 1568186936, 1568237509, 1568279142, 1568312908, 1568339752, 1568360503, 1568375889, 1568386553,
+ 1568393062, 1568395921, 1568395582, 1568392450, 1568386895, 1568379252, 1568369831, 1568358921, 1568346793,
+ 1568333699, 1568319881, 1568305568, 1568290979, 1568276322, 1568261795, 1568247587, 1568233876, 1568220830,
+ 1568208605, 1568197346, 1568187184, 1568178237, 1568170607, 1568164384, 1568159638, 1568156425, 1568154783,
+ 1568154732, 1568156276, 1568159400, 1568164071, 1568170240, 1568177841, 1568186791, 1568196993, 1568208336,
+ 1568220695, 1568233934, 1568247907, 1568262461, 1568277433, 1568292659, -1568307970, -1568323196, -1568338169,
+ -1568352723, -1568366698, -1568379938, -1568392298, -1568403642, -1568413846, -1568422797, -1568430399, -1568436568,
+ -1568441238, -1568444360, -1568445899, -1568445842, -1568444189, -1568440959, -1568436189, -1568429930, -1568422249,
+ -1568413227, -1568402961, -1568391555, -1568379128, -1568365802, -1568351710, -1568336985, -1568321763, -1568306179,
+ -1568290362, -1568274432, -1568258500, -1568242658, -1568226981, -1568211514, -1568196277, -1568181247, -1568166364,
+ -1568151514, -1568136526, -1568121163, -1568105112, -1568087973, -1568069251, -1568048342, -1568024520, -1567996924,
+ -1567964542, -1567926198, -1567880531, -1567825982, -1567760771, -1567682880, -1567590033, -1567479671, -1567348935,
+ -1567194644, -1567013268, -1566800908, -1566553276, -1566265667, -1565932945, -1565549513, -1565109302, -1564605744,
+ -1564031762, -1563379748, -1562641555, -1561808482, -1560871269, -1559820088, -1558644542, -1557333666, -1555875931,
+ -1554259255, -1552471010, -1550498044, -1548326699, -1545942840, -1543331880, -1540478822, -1537368293, -1533984594,
+ -1530311749, -1526333557, -1522033659, -1517395595, -1512402882, -1507039082, -1501287884, -1495133187, -1488559185,
+ -1481550459, -1474092069, -1466169648, -1457769502, -1448878707, -1439485206, -1429577913, -1419146803, -1408183016,
+ -1396678943, -1384628319, -1372026306, -1358869573, -1345156368, -1330886582, -1316061806, -1300685380, -1284762427,
+ -1268299884, -1251306514, -1233792909, -1215771486, -1197256464, -1178263828, -1158811290, -1138918228, -1118605615,
+ -1097895946, -1076813140, -1055382446, -1033630329, -1011584359, -989273085, -966725907, -943972946, -921044904,
+ -897972934, -874788497, -851523227, -828208798, -804876792, -781558570, -758285150, -735087092, -711994385,
+ -689036342, -666241506, -643637563, -621251256, -599108313, -577233388, -555649994, -534380464, -513445903,
+ -492866154, -472659775, -452844015, -433434798, -414446719, -395893041, -377785693, -360135279, -342951091,
+ -326241124, -310012090, -294269448, -279017421, -264259031, -249996126, -236229411, -222958488, -210181887,
+ -197897110, -186100669, -174788126, -163954142, -153592518, -143696242, -134257536, -125267909, -116718201,
+ -108598638, -100898882, -93608083, -86714933, -80207718, -74074369, -68302521, -62879558, -57792672,
+ -53028908, -48575221, -44418518, -40545711, -36943757, -33599707, -30500746, -27634227, -24987716,
+ -22549018, -20306212, -18247679, -16362124, -14638601, -13066533, -11635723, -10336374, -9159092,
+ -8094899, -7135237, -6271969, -5497377, -4804166, -4185453, -3634765, -3146030, -2713568,
+ -2332079, -1996632, -1702653, -1445912, -1222503, -1028839, -861625, -717855, -594786,
+ -489927, -401025, -326046, -263164, -210741, -167319, -131601, -102441, -78831,
+ -59886, -44835, -33011, -23837, -16822, -11545, -7652, -4848, -2886,
+ -1564, -718, -214 };
+RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_5ms_IP[840] = {
+ 76, 257, 559, 1032, 1734, 2736, 4127, 6013, 8519,
+ 11795, 16017, 21388, 28146, 36565, 46958, 59681, 75141, 93793,
+ 116154, 142798, 174368, 211576, 255213, 306147, 365337, 433830, 512771,
+ 603404, 707083, 825270, 959545, 1111607, 1283278, 1476512, 1693391, 1936135,
+ 2207099, 2508779, 2843816, 3214988, 3625222, 4077586, 4575292, 5121693, 5720282,
+ 6374686, 7088668, 7866117, 8711044, 9627575, 10619947, 11692493, 12849640, 14095892,
+ 15435823, 16874063, 18415286, 20064193, 21825499, 23703917, 25704138, 27830817, 30088554,
+ 32481870, 35015193, 37692833, 40518962, 43497594, 46632560, 49927486, 53385775, 57010578,
+ 60804774, 64770951, 68911378, 73227988, 77722354, 82395670, 87248734, 92281923, 97495181,
+ 102888003, 108459414, 114207966, 120131717, 126228227, 132494547, 138927218, 145522261, 152275182,
+ 159180971, 166234104, 173428552, 180757788, 188214801, 195792105, 203481764, 211275403, 219164235,
+ 227139085, 235190416, 243308359, 251482745, 259703138, 267958873, 276239090, 284532776, 292828806,
+ 301115982, 309383080, 317618887, 325812253, 333952128, 342027608, 350027981, 357942764, 365761752,
+ 373475051, 381073123, 388546818, 395887478, 403086861, 410137202, 417031278, 423762414, 430324505,
+ 436712040, 442920115, 448944445, 454781381, 460427907, 465881653, 471140887, 476204517, 481072084,
+ 485743749, 490220286, 494503064, 498594029, 502495687, 506211078, 509743756, 513097759, 516277584,
+ 519288161, 522134817, 524823252, 527359505, 529749922, 532001128, 534119994, 536113606, 537989238,
+ 539754317, 541416403, 542983151, 544462298, 545861626, 547188947, 548452077, 549658817, 550816937,
+ 551934153, 553018114, 554076391, 555116460, 556145691, 557171340, 558200539, 559240287, 560297445,
+ 561378728, 562490702, 563639778, 564832206, 566074075, 567371305, 568729649, 570154682, 571651805,
+ 573226236, 574883010, 576626970, 578462769, 580394858, 582427488, 584564698, 586810313, 589167940,
+ 591640954, 594232500, 596945481, 599782552, 602746115, 605838312, 609061015, 612415825, 615904060,
+ 619526756, 623284658, 627178213, 631207574, 635372590, 639672804, 644107457, 648675483, 653375510,
+ 658205862, 663164563, 668249336, 673457615, 678786542, 684232980, 689793518, 695464480, 701241935,
+ 707121707, 713099387, 719170342, 725329733, 731572527, 737893509, 744287298, 750748363, 757271038,
+ 763849540, 770477982, 777150393, 783860731, 790602903, 797370781, 804158216, 810959059, 817767172,
+ 824576448, 831380824, 838174297, 844950938, 851704905, 858430460, 865121975, 871773953, 878381029,
+ 884937988, 891439772, 897881487, 904258415, 910566018, 916799945, 922956036, 929030332, 935019072,
+ 940918701, 946725867, 952437431, 958050459, 963562228, 968970222, 974272134, 979465863, 984549513,
+ 989521388, 994379992, 999124027, 1003752385, 1008264148, 1012658583, 1016935141, 1021093445, 1025133296,
+ 1029054661, 1032857672, 1036542620, 1040109952, 1043560268, 1046894310, 1050112965, 1053217256, 1056208338,
+ 1059087494, 1061856131, 1064515771, 1067068050, 1069514712, 1071857603, 1074098665, 1076239931, 1078283519,
+ 1080231627, 1082086525, 1083850551, 1085526101, 1087115629, 1088621631, 1090046648, 1091393252, 1092664044,
+ 1093861644, 1094988685, 1096047808, 1097041655, 1097972860, 1098844046, 1099657818, 1100416756, 1101123410,
+ 1101780297, 1102389891, 1102954625, 1103476879, 1103958984, 1104403212, 1104811774, 1105186822, 1105530438,
+ 1105844638, 1106131370, 1106392508, 1106629854, 1106845137, 1107040012, 1107216060, 1107374784, 1107517617,
+ 1107645915, 1107760961, 1107863967, 1107956073, 1108038347, 1108111792, 1108177340, 1108235860, 1108288159,
+ 1108334979, 1108377006, 1108414868, 1108449137, 1108480336, 1108508935, 1108535359, 1108559986, 1108583153,
+ 1108605158, 1108626260, 1108646685, 1108666625, 1108686243, 1108705675, 1108725031, 1108744398, 1108763843,
+ 1108783413, 1108803139, 1108823037, 1108843110, 1108863348, 1108883733, 1108904238, 1108924827, 1108945461,
+ 1108966087, 1108986655, 1109007132, 1109027458, 1109047572, 1109067415, 1109086928, 1109106055, 1109124739,
+ 1109142927, 1109160566, 1109177606, 1109193997, 1109209694, 1109224653, 1109238833, 1109252194, 1109264701,
+ 1109276321, 1109287024, 1109296781, 1109305569, 1109313366, 1109320154, 1109325918, 1109330645, 1109334328,
+ 1109336959, 1109338535, 1109339057, 1109338528, 1109336954, 1109334342, 1109330704, 1109326055, 1109320411,
+ 1109313791, 1109306216, 1109297711, 1109288301, 1109278014, 1109266881, 1109254934, 1109242206, 1109228734,
+ 1109214554, 1109199706, 1109184228, 1109168164, 1109151555, 1109134445, 1109116879, 1109098903, 1109080563,
+ 1109061906, 1109042980, 1109023833, 1109004515, 1108985073, 1108965557, 1108946017, 1108926503, 1108907062,
+ 1108887746, 1108868601, 1108849679, 1108831026, 1108812690, 1108794719, 1108777158, 1108760054, 1108743451,
+ 1108727393, 1108711923, 1108697081, 1108682908, 1108669442, 1108656721, 1108644781, 1108633654, 1108623374,
+ 1108613969, 1108605469, 1108597899, 1108591283, 1108585643, 1108580997, 1108577362, 1108574752, 1108573178,
+ 1108572650, 1108573172, 1108574747, 1108577376, 1108581056, 1108585780, 1108591541, 1108598324, 1108606116,
+ 1108614899, 1108624650, 1108635346, 1108646959, 1108659460, 1108672814, 1108686987, 1108701939, 1108717629,
+ 1108734013, 1108751046, 1108768679, 1108786861, 1108805540, 1108824662, 1108844171, 1108864011, 1108884121,
+ 1108904445, 1108924921, 1108945488, -1108966087, -1108986655, -1109007132, -1109027458, -1109047572, -1109067415,
+ -1109086928, -1109106055, -1109124739, -1109142927, -1109160566, -1109177606, -1109193997, -1109209694, -1109224653,
+ -1109238833, -1109252194, -1109264701, -1109276321, -1109287024, -1109296781, -1109305569, -1109313366, -1109320154,
+ -1109325918, -1109330645, -1109334328, -1109336959, -1109338535, -1109339057, -1109338528, -1109336954, -1109334342,
+ -1109330704, -1109326055, -1109320411, -1109313791, -1109306216, -1109297711, -1109288301, -1109278014, -1109266881,
+ -1109254934, -1109242206, -1109228734, -1109214554, -1109199706, -1109184228, -1109168164, -1109151555, -1109134445,
+ -1109116879, -1109098903, -1109080563, -1109061906, -1109042980, -1109023833, -1109004515, -1108985073, -1108965557,
+ -1108946017, -1108926503, -1108907062, -1108887746, -1108868601, -1108849679, -1108831026, -1108812690, -1108794719,
+ -1108777158, -1108760054, -1108743451, -1108727393, -1108711923, -1108697081, -1108682908, -1108669442, -1108656721,
+ -1108644781, -1108633654, -1108623374, -1108613969, -1108605469, -1108597899, -1108591283, -1108585643, -1108580997,
+ -1108577362, -1108574752, -1108573178, -1108572650, -1108573172, -1108574747, -1108577376, -1108581056, -1108585780,
+ -1108591541, -1108598324, -1108606116, -1108614899, -1108624650, -1108635346, -1108646959, -1108659460, -1108672814,
+ -1108686987, -1108701939, -1108717629, -1108734013, -1108751046, -1108768679, -1108786861, -1108805540, -1108824662,
+ -1108844171, -1108864011, -1108884121, -1108904445, -1108924921, -1108945488, -1108966059, -1108986562, -1109006925,
+ -1109027070, -1109046909, -1109066353, -1109085302, -1109103653, -1109121290, -1109138090, -1109153916, -1109168619,
+ -1109182038, -1109193990, -1109204280, -1109212687, -1109218972, -1109222869, -1109224086, -1109222302, -1109217164,
+ -1109208286, -1109195243, -1109177572, -1109154771, -1109126288, -1109091528, -1109049845, -1109000541, -1108942861,
+ -1108875994, -1108799068, -1108711146, -1108611228, -1108498242, -1108371047, -1108228427, -1108069090, -1107891663,
+ -1107694692, -1107476636, -1107235870, -1106970675, -1106679239, -1106359654, -1106009912, -1105627904, -1105211414,
+ -1104758117, -1104265576, -1103731240, -1103152437, -1102526375, -1101850136, -1101120673, -1100334807, -1099489225,
+ -1098580473, -1097604958, -1096558943, -1095438542, -1094239723, -1092958302, -1091589944, -1090130161, -1088574313,
+ -1086917606, -1085155099, -1083281700, -1081292171, -1079181138, -1076943086, -1074572374, -1072063243, -1069409818,
+ -1066606126, -1063646105, -1060523618, -1057232468, -1053766415, -1050119192, -1046284528, -1042256165, -1038027882,
+ -1033593517, -1028946994, -1024082345, -1018993738, -1013675503, -1008122162, -1002328454, -996289366, -990000160,
+ -983456402, -976653990, -969589182, -962258626, -954659381, -946788949, -938645296, -930226877, -921532657,
+ -912562133, -903315354, -893792938, -883996084, -873926592, -863586870, -852979945, -842109472, -830979735,
+ -819595655, -807962787, -796087320, -783976072, -771636483, -759076610, -746305110, -733331233, -720164799,
+ -706816188, -693296313, -679616605, -665788980, -651825820, -637739943, -623544570, -609253297, -594880059,
+ -580439096, -565944918, -551412265, -536856066, -522291404, -507733472, -493197528, -478698857, -464252725,
+ -449874333, -435578778, -421381001, -407295749, -393337528, -379520558, -365858731, -352365567, -339054174,
+ -325937207, -313026827, -300334664, -287871784, -275648653, -263675105, -251960314, -240512770, -229340251,
+ -218449809, -207847746, -197539607, -187530166, -177823422, -168422593, -159330123, -150547678, -142076164,
+ -133915731, -126065794, -118525050, -111291498, -104362470, -97734652, -91404122, -85366377, -79616373,
+ -74148557, -68956911, -64034986, -59375949, -54972617, -50817502, -46902854, -43220698, -39762875,
+ -36521086, -33486923, -30651913, -28007548, -25545325, -23256770, -21133479, -19167136, -17349546,
+ -15672656, -14128580, -12709614, -11408260, -10217235, -9129491, -8138220, -7236869, -6419144,
+ -5679019, -5010736, -4408811, -3868031, -3383459, -2950426, -2564532, -2221640, -1917871,
+ -1649598, -1413439, -1206249, -1025112, -867332, -730423, -612103, -510279, -423042,
+ -348652, -285533, -232260, -187551, -150254, -119343, -93901, -73120, -56285,
+ -42770, -32029, -23588, -17037, -12025, -8254, -5472, -3467, -2064,
+ -1119, -513, -153 };
+RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_IP[1560] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 52, 175, 382,
+ 705, 1185, 1871, 2823, 4114, 5831, 8077, 10972, 14660,
+ 19303, 25092, 32244, 41009, 51670, 64545, 79996, 98427, 120290,
+ 146088, 176379, 211778, 252965, 300685, 355753, 419058, 491567, 574329,
+ 668476, 775231, 895906, 1031911, 1184750, 1356028, 1547453, 1760836, 1998091,
+ 2261242, 2552417, 2873848, 3227877, 3616948, 4043606, 4510498, 5020366, 5576047,
+ 6180463, 6836620, 7547602, 8316559, 9146706, 10041310, 11003683, 12037172, 13145144,
+ 14330983, 15598071, 16949778, 18389446, 19920381, 21545832, 23268982, 25092926, 27020662,
+ 29055072, 31198906, 33454766, 35825091, 38312140, 40917976, 43644450, 46493186, 49465569,
+ 52562726, 55785514, 59134509, 62609992, 66211939, 69940008, 73793535, 77771521, 81872629,
+ 86095178, 90437137, 94896125, 99469410, 104153908, 108946186, 113842469, 118838639, 123930249,
+ 129112527, 134380390, 139728454, 145151046, 150642225, 156195792, 161805313, 167464136, 173165413,
+ 178902121, 184667086, 190453005, 196252476, 202058015, 207862090, 213657145, 219435626, 225190009,
+ 230912827, 236596697, 242234348, 247818648, 253342624, 258799497, 264182697, 269485893, 274703012,
+ 279828312, 284856314, 289781856, 294600125, 299306665, 303897390, 308368599, 312716983, 316939635,
+ 321034059, 324998175, 328830319, 332529248, 336094136, 339524575, 342820570, 345982531, 349011267,
+ 351907976, 354674236, 357311989, 359823531, 362211496, 364478840, 366628822, 368664989, 370591159,
+ 372411396, 374129997, 375751467, 377280502, 378721970, 380080887, 381362400, 382571769, 383714343,
+ 384795547, 385820862, 386795806, 387725921, 388616754, 389473844, 390302710, 391108835, 391897652,
+ 392674541, 393444809, 394213686, 394986316, 395767747, 396562926, 397376691, 398213764, 399078748,
+ 399976120, 400910228, 401885285, 402905364, 403974398, 405096172, 406274322, 407512329, 408813519,
+ 410181054, 411617935, 413126993, 414710888, 416372104, 418112946, 419935539, 421841819, 423833534,
+ 425912241, 428079300, 430335872, 432682921, 435121205, 437651278, 440273491, 442987985, 445794697,
+ 448693355, 451683483, 454764399, 457935219, 461194860, 464542039, 467975283, 471492928, 475093126,
+ 478773851, 482532904, 486367920, 490276375, 494255591, 498302751, 502414896, 506588946, 510821698,
+ 515109841, 519449966, 523838572, 528272075, 532746823, 537259100, 541805139, 546381131, 550983233,
+ 555607579, 560250290, 564907481, 569575271, 574249791, 578927195, 583603665, 588275420, 592938724,
+ 597589893, 602225302, 606841390, 611434670, 616001729, 620539240, 625043960, 629512740, 633942527,
+ 638330370, 642673418, 646968929, 651214270, 655406919, 659544468, 663624624, 667645211, 671604169,
+ 675499557, 679329551, 683092449, 686786663, 690410727, 693963289, 697443117, 700849092, 704180212,
+ 707435589, 710614445, 713716116, 716740046, 719685788, 722553001, 725341451, 728051005, 730681634,
+ 733233409, 735706498, 738101168, 740417780, 742656787, 744818734, 746904257, 748914076, 750848997,
+ 752709910, 754497783, 756213660, 757858664, 759433984, 760940881, 762380680, 763754766, 765064584,
+ 766311629, 767497450, 768623637, 769691823, 770703677, 771660899, 772565218, 773418381, 774222155,
+ 774978320, 775688661, 776354967, 776979026, 777562617, 778107510, 778615459, 779088198, 779527438,
+ 779934863, 780312126, 780660846, 780982606, 781278948, 781551373, 781801337, 782030250, 782239474,
+ 782430322, 782604056, 782761888, 782904976, 783034427, 783151295, 783256582, 783351237, 783436158,
+ 783512191, 783580133, 783640729, 783694677, 783742630, 783785193, 783822926, 783856349, 783885939,
+ 783912134, 783935335, 783955909, 783974185, 783990464, 784005015, 784018080, 784029874, 784040589,
+ 784050394, 784059435, 784067843, 784075728, 784083188, 784090303, 784097145, 784103769, 784110225,
+ 784116552, 784122782, 784128939, 784135042, 784141107, 784147142, 784153152, 784159138, 784165118,
+ 784171086, 784177037, 784182968, 784188874, 784194749, 784200591, 784206393, 784212151, 784217862,
+ 784223520, 784229122, 784234663, 784240139, 784245546, 784250879, 784256136, 784261311, 784266402,
+ 784271403, 784276313, 784281126, 784285841, 784290452, 784294958, 784299354, 784303638, 784307807,
+ 784311858, 784315788, 784319595, 784323276, 784326828, 784330250, 784333539, 784336693, 784339710,
+ 784342589, 784345327, 784347923, 784350376, 784352685, 784354847, 784356862, 784358729, 784360447,
+ 784362016, 784363434, 784364702, 784365818, 784366783, 784367596, 784368257, 784368766, 784369124,
+ 784369331, 784369387, 784369292, 784369047, 784368653, 784368111, 784367421, 784366584, 784365602,
+ 784364475, 784363205, 784361793, 784360241, 784358550, 784356721, 784354756, 784352657, 784350426,
+ 784348065, 784345575, 784342958, 784340217, 784337354, 784334371, 784331270, 784328053, 784324723,
+ 784321282, 784317734, 784314079, 784310321, 784306463, 784302507, 784298456, 784294312, 784290078,
+ 784285758, 784281354, 784276869, 784272306, 784267667, 784262957, 784258177, 784253332, 784248423,
+ 784243454, 784238429, 784233349, 784228220, 784223043, 784217822, 784212560, 784207260, 784201926,
+ 784196560, 784191167, 784185749, 784180310, 784174852, 784169380, 784163896, 784158404, 784152907,
+ 784147408, 784141911, 784136419, 784130935, 784125463, 784120006, 784114567, 784109150, 784103757,
+ 784098392, 784093059, 784087760, 784082499, 784077278, 784072102, 784066974, 784061896, 784056872,
+ 784051904, 784046997, 784042152, 784037374, 784032665, 784028028, 784023466, 784018982, 784014580,
+ 784010261, 784006029, 784001887, 783997837, 783993883, 783990026, 783986270, 783982617, 783979069,
+ 783975630, 783972302, 783969087, 783965987, 783963005, 783960143, 783957404, 783954788, 783952300,
+ 783949939, 783947709, 783945612, 783943648, 783941820, 783940130, 783938578, 783937167, 783935898,
+ 783934772, 783933790, 783932954, 783932264, 783931722, 783931328, 783931084, 783930989, 783931045,
+ 783931251, 783931609, 783932118, 783932779, 783933592, 783934556, 783935672, 783936938, 783938356,
+ 783939924, 783941641, 783943507, 783945521, 783947682, 783949989, 783952441, 783955036, 783957773,
+ 783960650, 783963666, 783966818, 783970106, 783973526, 783977077, 783980756, 783984561, 783988490,
+ 783992539, 783996706, 784000989, 784005383, 784009887, 784014497, 784019210, 784024022, 784028930,
+ 784033930, 784039019, 784044193, 784049448, 784054780, 784060186, 784065661, 784071201, 784076801,
+ 784082459, 784088168, 784093926, 784099727, 784105568, 784111443, 784117348, 784123278, 784129229,
+ 784135197, 784141176, 784147163, 784153152, 784159138, 784165118, 784171086, 784177037, 784182968,
+ 784188874, 784194749, 784200591, 784206393, 784212151, 784217862, 784223520, 784229122, 784234663,
+ 784240139, 784245546, 784250879, 784256136, 784261311, 784266402, 784271403, 784276313, 784281126,
+ 784285841, 784290452, 784294958, 784299354, 784303638, 784307807, 784311858, 784315788, 784319595,
+ 784323276, 784326828, 784330250, 784333539, 784336693, 784339710, 784342589, 784345327, 784347923,
+ 784350376, 784352685, 784354847, 784356862, 784358729, 784360447, 784362016, 784363434, 784364702,
+ 784365818, 784366783, 784367596, 784368257, 784368766, 784369124, 784369331, 784369387, 784369292,
+ 784369047, 784368653, 784368111, 784367421, 784366584, 784365602, 784364475, 784363205, 784361793,
+ 784360241, 784358550, 784356721, 784354756, 784352657, 784350426, 784348065, 784345575, 784342958,
+ 784340217, 784337354, 784334371, 784331270, 784328053, 784324723, 784321282, 784317734, 784314079,
+ 784310321, 784306463, 784302507, 784298456, 784294312, 784290078, 784285758, 784281354, 784276869,
+ 784272306, 784267667, 784262957, 784258177, 784253332, 784248423, 784243454, 784238429, 784233349,
+ 784228220, 784223043, 784217822, 784212560, 784207260, 784201926, 784196560, 784191167, 784185749,
+ 784180310, 784174852, 784169380, 784163896, 784158404, 784152907, -784147408, -784141911, -784136419,
+ -784130935, -784125463, -784120006, -784114567, -784109150, -784103757, -784098392, -784093059, -784087760,
+ -784082499, -784077278, -784072102, -784066974, -784061896, -784056872, -784051904, -784046997, -784042152,
+ -784037374, -784032665, -784028028, -784023466, -784018982, -784014580, -784010261, -784006029, -784001887,
+ -783997837, -783993883, -783990026, -783986270, -783982617, -783979069, -783975630, -783972302, -783969087,
+ -783965987, -783963005, -783960143, -783957404, -783954788, -783952300, -783949939, -783947709, -783945612,
+ -783943648, -783941820, -783940130, -783938578, -783937167, -783935898, -783934772, -783933790, -783932954,
+ -783932264, -783931722, -783931328, -783931084, -783930989, -783931045, -783931251, -783931609, -783932118,
+ -783932779, -783933592, -783934556, -783935672, -783936938, -783938356, -783939924, -783941641, -783943507,
+ -783945521, -783947682, -783949989, -783952441, -783955036, -783957773, -783960650, -783963666, -783966818,
+ -783970106, -783973526, -783977077, -783980756, -783984561, -783988490, -783992539, -783996706, -784000989,
+ -784005383, -784009887, -784014497, -784019210, -784024022, -784028930, -784033930, -784039019, -784044193,
+ -784049448, -784054780, -784060186, -784065661, -784071201, -784076801, -784082459, -784088168, -784093926,
+ -784099727, -784105568, -784111443, -784117348, -784123278, -784129229, -784135197, -784141176, -784147163,
+ -784153152, -784159138, -784165118, -784171086, -784177037, -784182968, -784188874, -784194749, -784200591,
+ -784206393, -784212151, -784217862, -784223520, -784229122, -784234663, -784240139, -784245546, -784250879,
+ -784256136, -784261311, -784266402, -784271403, -784276313, -784281126, -784285841, -784290452, -784294958,
+ -784299354, -784303638, -784307807, -784311858, -784315788, -784319595, -784323276, -784326828, -784330250,
+ -784333539, -784336693, -784339710, -784342589, -784345327, -784347923, -784350376, -784352685, -784354847,
+ -784356862, -784358729, -784360447, -784362016, -784363434, -784364702, -784365818, -784366783, -784367596,
+ -784368257, -784368766, -784369124, -784369331, -784369387, -784369292, -784369047, -784368653, -784368111,
+ -784367421, -784366584, -784365602, -784364475, -784363205, -784361793, -784360241, -784358550, -784356721,
+ -784354756, -784352657, -784350426, -784348065, -784345575, -784342958, -784340217, -784337354, -784334371,
+ -784331270, -784328053, -784324723, -784321282, -784317734, -784314079, -784310321, -784306463, -784302507,
+ -784298456, -784294312, -784290078, -784285758, -784281354, -784276869, -784272306, -784267667, -784262957,
+ -784258177, -784253332, -784248423, -784243454, -784238429, -784233349, -784228220, -784223043, -784217822,
+ -784212560, -784207260, -784201926, -784196560, -784191167, -784185749, -784180310, -784174852, -784169380,
+ -784163896, -784158404, -784152907, -784147408, -784141911, -784136419, -784130935, -784125463, -784120006,
+ -784114567, -784109150, -784103757, -784098392, -784093059, -784087760, -784082499, -784077278, -784072102,
+ -784066974, -784061896, -784056872, -784051904, -784046997, -784042152, -784037374, -784032665, -784028028,
+ -784023466, -784018982, -784014580, -784010261, -784006029, -784001887, -783997837, -783993883, -783990026,
+ -783986270, -783982617, -783979069, -783975630, -783972302, -783969087, -783965987, -783963005, -783960143,
+ -783957404, -783954788, -783952300, -783949939, -783947709, -783945612, -783943648, -783941820, -783940130,
+ -783938578, -783937167, -783935898, -783934772, -783933790, -783932954, -783932264, -783931722, -783931328,
+ -783931084, -783930989, -783931045, -783931251, -783931609, -783932118, -783932779, -783933592, -783934556,
+ -783935672, -783936938, -783938356, -783939924, -783941641, -783943507, -783945521, -783947682, -783949989,
+ -783952441, -783955036, -783957773, -783960650, -783963666, -783966818, -783970106, -783973526, -783977077,
+ -783980756, -783984561, -783988490, -783992539, -783996706, -784000989, -784005383, -784009887, -784014497,
+ -784019210, -784024022, -784028930, -784033930, -784039019, -784044193, -784049448, -784054780, -784060186,
+ -784065661, -784071201, -784076801, -784082459, -784088168, -784093926, -784099727, -784105568, -784111443,
+ -784117348, -784123278, -784129229, -784135197, -784141176, -784147163, -784153131, -784159068, -784164963,
+ -784170795, -784176541, -784182173, -784187657, -784192951, -784198007, -784202769, -784207169, -784211130,
+ -784214559, -784217353, -784219391, -784220535, -784220630, -784219497, -784216937, -784212727, -784206617,
+ -784198327, -784187551, -784173947, -784157141, -784136723, -784112243, -784083213, -784049101, -784009333,
+ -783963287, -783910294, -783849634, -783780538, -783702180, -783613679, -783514100, -783402445, -783277658,
+ -783138617, -782984141, -782812977, -782623808, -782415247, -782185834, -781934039, -781658253, -781356794,
+ -781027899, -780669728, -780280356, -779857776, -779399894, -778904531, -778369419, -777792197, -777170416,
+ -776501532, -775782908, -775011810, -774185411, -773300787, -772354919, -771344691, -770266894, -769118226,
+ -767895293, -766594614, -765212620, -763745664, -762190019, -760541889, -758797411, -756952664, -755003678,
+ -752946440, -750776904, -748491005, -746084664, -743553805, -740894366, -738102311, -735173645, -732104432,
+ -728890802, -725528974, -722015270, -718346128, -714518120, -710527972, -706372573, -702048997, -697554517,
+ -692886621, -688043026, -683021694, -677820848, -672438982, -666874876, -661127608, -655196568, -649081463,
+ -642782332, -636299553, -629633851, -622786302, -615758346, -608551783, -601168786, -593611894, -585884022,
+ -577988458, -569928861, -561709265, -553334069, -544808041, -536136306, -527324347, -518377994, -509303418,
+ -500107123, -490795932, -481376983, -471857712, -462245842, -452549370, -442776550, -432935882, -423036090,
+ -413086109, -403095064, -393072251, -383027119, -372969246, -362908319, -352854112, -342816459, -332805234,
+ -322830326, -312901609, -303028921, -293222034, -283490629, -273844269, -264292369, -254844170, -245508712,
+ -236294804, -227211000, -218265568, -209466468, -200821323, -192337394, -184021561, -175880295, -167919639,
+ -160145191, -152562081, -145174961, -137987988, -131004813, -124228572, -117661879, -111306824, -105164969,
+ -99237348, -93524475, -88026347, -82742454, -77671790, -72812867, -68163733, -63721988, -59484805,
+ -55448955, -51610827, -47966456, -44511550, -41241516, -38151492, -35236370, -32490831, -29909374,
+ -27486341, -25215951, -23092326, -21109518, -19261540, -17542387, -15946062, -14466601, -13098096,
+ -11834709, -10670701, -9600439, -8618419, -7719279, -6897809, -6148962, -5467868, -4849835,
+ -4290361, -3785136, -3330046, -2921175, -2554807, -2227423, -1935704, -1676526, -1446955,
+ -1244248, -1065844, -909363, -772594, -653495, -550182, -460924, -384136, -318370,
+ -262309, -214759, -174641, -140984, -112917, -89663, -70531, -54908, -42257,
+ -32104, -24037, -17698, -12781, -9020, -6190, -4103, -2600, -1548,
+ -839, -385, -115 };
+#endif /* ENABLE_HR_MODE */
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2] = { LowDelayShapes_n960_N480_HRA_2_5ms_IP,
+ LowDelayShapes_n960_N960_HRA_2_5ms_IP };
+
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2] = { LowDelayShapes_n960_N480_HRA_5ms_IP,
+ LowDelayShapes_n960_N960_HRA_5ms_IP };
+
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2] = { LowDelayShapes_n960_N480_HRA_IP,
+ LowDelayShapes_n960_N960_HRA_IP };
+
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2] = { LowDelayShapes_n960_N480_HRA_7_5ms_IP,
+ LowDelayShapes_n960_N960_HRA_7_5ms_IP };
+# endif
+#endif /* ENABLE_HR_MODE */
+
+RAM_ALIGN const Word16 pitch_max[5] = {MAX_PITCH_8K, MAX_PITCH_16K, MAX_PITCH_24K, MAX_PITCH_32K, MAX_PITCH_48K};
+RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ] = {20316, 23592, 26869, 30146, 30146
+# ifdef ENABLE_HR_MODE
+ , 30146
+# endif
+ };
+/* high pass filter Q15 */
+RAM_ALIGN const Word16 TDC_high_16[11] = {(Word16)0x0000, (Word16)0xfd60, (Word16)0xf7ab, (Word16)0xefec,
+ (Word16)0xe910, (Word16)0x66c2, (Word16)0xe910, (Word16)0xefec,
+ (Word16)0xf7ab, (Word16)0xfd60, (Word16)0x0000};
+
+RAM_ALIGN const Word16 TDC_high_32[11] = {(Word16)0xf962, (Word16)0xf87d, (Word16)0xf581, (Word16)0xf2e5,
+ (Word16)0xf11a, (Word16)0x7076, (Word16)0xf11a, (Word16)0xf2e5,
+ (Word16)0xf581, (Word16)0xf87d, (Word16)0xf962};
+
+RAM_ALIGN const Word16 TDC_high_16_harm[11] = {(Word16) 174, (Word16) 0, (Word16) -1442, (Word16) 0,
+ (Word16) 8641, (Word16) 18022, (Word16) 8641, (Word16) 0,
+ (Word16) -1442, (Word16) 0, (Word16) 174};
+
+RAM_ALIGN const Word16 TDC_high_32_harm[11] = {(Word16) -174, (Word16) -121, (Word16) -459, (Word16) 590,
+ (Word16) 8743, (Word16) 16355, (Word16) 8743, (Word16) 590,
+ (Word16) -459, (Word16) -121, (Word16) -174};
+
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N80[130] = {
+ -15, -43, -94, -171, -277, -414, -580, -771, -981, -1201, -1423, -1638, -1836,
+ -2008, -2145, -2240, -2286, -2279, -2214, -2085, -1889, -1621, -1274, -842, -318, 305,
+ 1034, 1876, 2833, 3906, 5091, 6379, 7754, 9198, 10683, 12179, 13652, 15068, 16390,
+ 17588, 18634, 19509, 20201, 20712, 21051, 21237, 21297, 21263, 21168, 21044, 20918, 20797,
+ 20701, 20627, 20571, 20529, 20499, 20479, 20468, 20463, 20464, 20469, 20477, 20486, 20495,
+ 20503, 20509, 20514, 20516, 20518, 20520, 20524, 20530, 20540, 20556, 20576, 20602, 20633,
+ 20668, 20705, -20743, -20781, -20816, -20847, -20873, -20894, -20910, -20920, -20927, -20930, -20932,
+ -20934, -20937, -20942, -20948, -20956, -20966, -20975, -20982, -20988, -20989, -20984, -20972, -20952,
+ -20921, -20879, -20822, -20747, -20652, -20532, -20359, -20121, -19785, -19318, -18689, -17873, -16855,
+ -15636, -14231, -12670, -10997, -9266, -7542, -5889, -4373, -3051, -1965, -1136, -560, -207};
+#else
+#define LowDelayShapes_n960_N80 NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N160[260] = {
+ -14, -29, -49, -76, -112, -156, -210, -275, -350, -437, -534, -641, -759, -885,
+ -1020, -1163, -1311, -1464, -1620, -1777, -1935, -2090, -2242, -2390, -2530, -2661, -2783, -2893,
+ -2990, -3073, -3140, -3191, -3224, -3238, -3233, -3208, -3162, -3094, -3003, -2889, -2751, -2587,
+ -2397, -2180, -1935, -1661, -1355, -1018, -648, -244, 197, 674, 1190, 1745, 2340, 2976,
+ 3652, 4370, 5129, 5928, 6766, 7642, 8553, 9496, 10470, 11469, 12490, 13529, 14579, 15637,
+ 16696, 17750, 18792, 19817, 20819, 21791, 22727, 23621, 24469, 25264, 26004, 26685, 27304, 27858,
+ 28348, 28773, 29134, 29433, 29672, 29855, 29986, 30070, 30112, 30117, 30092, 30043, 29976, 29895,
+ 29807, 29716, 29632, 29536, 29451, 29374, 29307, 29247, 29195, 29149, 29109, 29075, 29045, 29020,
+ 28999, 28982, 28968, 28957, 28949, 28943, 28940, 28939, 28940, 28942, 28946, 28950, 28956, 28962,
+ 28968, 28975, 28981, 28987, 28993, 28998, 29002, 29006, 29009, 29012, 29014, 29015, 29017, 29018,
+ 29019, 29021, 29024, 29027, 29031, 29037, 29044, 29053, 29064, 29077, 29091, 29108, 29126, 29146,
+ 29168, 29192, 29216, 29242, 29268, 29295, -29322, -29349, -29376, -29401, -29426, -29450, -29472, -29492,
+ -29511, -29527, -29542, -29555, -29566, -29575, -29583, -29589, -29593, -29596, -29599, -29601, -29602, -29603,
+ -29605, -29606, -29608, -29611, -29614, -29618, -29623, -29628, -29634, -29640, -29646, -29653, -29660, -29666,
+ -29671, -29676, -29680, -29682, -29683, -29682, -29678, -29673, -29664, -29653, -29639, -29621, -29600, -29574,
+ -29544, -29509, -29469, -29423, -29370, -29310, -29243, -29167, -29083, -28988, -28861, -28718, -28551, -28351,
+ -28114, -27834, -27505, -27121, -26677, -26168, -25591, -24943, -24223, -23431, -22569, -21639, -20644, -19592,
+ -18487, -17338, -16154, -14944, -13719, -12491, -11270, -10068, -8898, -7771, -6698, -5689, -4753, -3898,
+ -3130, -2452, -1866, -1371, -964, -640, -392, -198};
+#else
+#define LowDelayShapes_n960_N160 NULL
+#endif
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N240[390] = {
+ -9, -17, -26, -37, -50, -66, -86, -108, -134, -164, -197, -234, -275, -320,
+ -369, -422, -479, -539, -603, -670, -741, -814, -891, -969, -1050, -1132, -1216, -1301,
+ -1387, -1473, -1558, -1643, -1728, -1810, -1892, -1971, -2047, -2120, -2190, -2256, -2318, -2376,
+ -2429, -2477, -2519, -2556, -2586, -2611, -2629, -2640, -2645, -2642, -2632, -2614, -2589, -2556,
+ -2515, -2466, -2408, -2341, -2266, -2182, -2088, -1985, -1872, -1748, -1615, -1471, -1316, -1150,
+ -972, -783, -582, -368, -141, 99, 352, 619, 899, 1194, 1503, 1827, 2166, 2519,
+ 2888, 3271, 3669, 4082, 4510, 4952, 5408, 5878, 6362, 6857, 7365, 7885, 8414, 8954,
+ 9502, 10058, 10621, 11189, 11761, 12335, 12912, 13488, 14063, 14635, 15203, 15764, 16319, 16864,
+ 17399, 17922, 18431, 18926, 19405, 19866, 20309, 20732, 21135, 21517, 21876, 22213, 22526, 22817,
+ 23083, 23326, 23546, 23743, 23916, 24068, 24198, 24308, 24397, 24469, 24522, 24560, 24582, 24592,
+ 24589, 24575, 24552, 24522, 24485, 24443, 24398, 24349, 24300, 24252, 24209, 24155, 24104, 24058,
+ 24014, 23974, 23938, 23904, 23873, 23844, 23818, 23794, 23773, 23753, 23735, 23719, 23705, 23692,
+ 23681, 23670, 23662, 23654, 23647, 23642, 23638, 23634, 23632, 23630, 23629, 23629, 23629, 23630,
+ 23632, 23634, 23636, 23639, 23642, 23645, 23648, 23652, 23655, 23658, 23662, 23665, 23669, 23672,
+ 23674, 23677, 23680, 23682, 23684, 23686, 23687, 23688, 23689, 23690, 23691, 23692, 23693, 23693,
+ 23694, 23695, 23696, 23697, 23699, 23701, 23703, 23706, 23710, 23714, 23718, 23723, 23729, 23736,
+ 23743, 23751, 23760, 23769, 23779, 23790, 23801, 23813, 23825, 23838, 23851, 23865, 23879, 23894,
+ 23908, 23923, -23938, -23952, -23967, -23981, -23996, -24010, -24023, -24036, -24049, -24061, -24072, -24083,
+ -24093, -24102, -24111, -24119, -24127, -24133, -24139, -24145, -24149, -24153, -24157, -24160, -24162, -24164,
+ -24166, -24167, -24168, -24169, -24170, -24171, -24171, -24172, -24173, -24174, -24175, -24176, -24178, -24179,
+ -24181, -24184, -24186, -24189, -24192, -24195, -24198, -24202, -24205, -24209, -24213, -24216, -24219, -24223,
+ -24226, -24228, -24231, -24233, -24234, -24235, -24236, -24236, -24235, -24233, -24230, -24227, -24222, -24217,
+ -24210, -24202, -24193, -24183, -24171, -24158, -24143, -24127, -24109, -24089, -24067, -24043, -24017, -23988,
+ -23957, -23923, -23886, -23847, -23804, -23758, -23708, -23655, -23584, -23509, -23427, -23336, -23234, -23119,
+ -22990, -22846, -22685, -22506, -22307, -22087, -21845, -21580, -21291, -20977, -20638, -20272, -19880, -19462,
+ -19018, -18549, -18054, -17536, -16995, -16432, -15849, -15248, -14630, -13997, -13353, -12698, -12036, -11369,
+ -10700, -10032, -9367, -8709, -8059, -7422, -6800, -6196, -5611, -5050, -4513, -4004, -3523, -3073,
+ -2655, -2269, -1917, -1598, -1312, -1059, -837, -646, -484, -350, -239, -127};
+#else
+#define LowDelayShapes_n960_N240 NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N320[520] = {
+ -6, -12, -17, -23, -30, -39, -48, -60, -72, -86, -102, -119, -138, -159,
+ -182, -207, -234, -262, -293, -325, -359, -396, -434, -473, -515, -558, -603, -649,
+ -697, -746, -797, -848, -900, -954, -1008, -1062, -1118, -1173, -1229, -1285, -1340, -1396,
+ -1451, -1505, -1559, -1612, -1664, -1715, -1764, -1813, -1859, -1904, -1947, -1988, -2027, -2064,
+ -2098, -2130, -2159, -2186, -2210, -2230, -2248, -2263, -2275, -2283, -2289, -2290, -2289, -2283,
+ -2274, -2262, -2245, -2225, -2201, -2173, -2141, -2105, -2065, -2020, -1971, -1918, -1860, -1797,
+ -1730, -1658, -1582, -1500, -1414, -1322, -1225, -1122, -1014, -901, -782, -657, -526, -389,
+ -246, -97, 59, 221, 390, 565, 748, 937, 1133, 1336, 1547, 1764, 1989, 2221,
+ 2460, 2707, 2961, 3222, 3490, 3765, 4048, 4338, 4634, 4937, 5246, 5562, 5884, 6212,
+ 6546, 6885, 7229, 7578, 7932, 8289, 8650, 9014, 9382, 9751, 10123, 10496, 10870, 11244,
+ 11619, 11992, 12365, 12736, 13105, 13471, 13833, 14192, 14546, 14895, 15239, 15576, 15907, 16231,
+ 16547, 16856, 17155, 17446, 17727, 17999, 18261, 18512, 18753, 18983, 19202, 19409, 19605, 19790,
+ 19963, 20125, 20275, 20414, 20541, 20658, 20764, 20858, 20943, 21017, 21082, 21137, 21184, 21221,
+ 21251, 21273, 21287, 21295, 21297, 21293, 21285, 21271, 21254, 21233, 21209, 21182, 21154, 21124,
+ 21092, 21060, 21028, 20999, 20972, 20935, 20902, 20870, 20839, 20811, 20784, 20758, 20734, 20712,
+ 20691, 20671, 20653, 20635, 20619, 20604, 20590, 20577, 20565, 20554, 20543, 20534, 20525, 20517,
+ 20509, 20502, 20496, 20491, 20486, 20481, 20477, 20474, 20471, 20469, 20467, 20465, 20464, 20464,
+ 20463, 20463, 20463, 20464, 20465, 20466, 20467, 20468, 20470, 20472, 20474, 20476, 20478, 20480,
+ 20482, 20485, 20487, 20489, 20491, 20494, 20496, 20498, 20500, 20502, 20504, 20505, 20507, 20508,
+ 20510, 20511, 20512, 20513, 20514, 20515, 20516, 20516, 20517, 20517, 20518, 20518, 20519, 20519,
+ 20519, 20520, 20521, 20521, 20522, 20523, 20524, 20526, 20527, 20529, 20531, 20533, 20536, 20539,
+ 20542, 20546, 20549, 20554, 20558, 20563, 20568, 20573, 20579, 20586, 20592, 20599, 20606, 20613,
+ 20621, 20629, 20637, 20646, 20655, 20663, 20672, 20682, 20691, 20700, 20710, 20720, -20729, -20739,
+ -20748, -20758, -20767, -20776, -20785, -20794, -20803, -20812, -20820, -20828, -20836, -20843, -20851, -20857,
+ -20864, -20870, -20876, -20882, -20887, -20892, -20896, -20901, -20905, -20908, -20911, -20914, -20917, -20919,
+ -20921, -20923, -20925, -20926, -20927, -20928, -20929, -20930, -20931, -20931, -20932, -20932, -20933, -20933,
+ -20934, -20934, -20935, -20935, -20936, -20937, -20938, -20939, -20940, -20941, -20943, -20944, -20946, -20947,
+ -20949, -20951, -20953, -20955, -20958, -20960, -20962, -20964, -20967, -20969, -20971, -20974, -20976, -20978,
+ -20980, -20982, -20983, -20985, -20986, -20987, -20988, -20989, -20989, -20989, -20988, -20988, -20986, -20985,
+ -20983, -20980, -20978, -20974, -20970, -20966, -20961, -20955, -20949, -20942, -20934, -20926, -20917, -20907,
+ -20896, -20885, -20873, -20859, -20845, -20830, -20814, -20796, -20778, -20758, -20737, -20714, -20690, -20665,
+ -20638, -20610, -20580, -20548, -20515, -20480, -20433, -20384, -20333, -20279, -20220, -20155, -20085, -20008,
+ -19924, -19833, -19734, -19627, -19511, -19385, -19249, -19103, -18946, -18778, -18598, -18406, -18202, -17986,
+ -17757, -17515, -17260, -16993, -16713, -16421, -16116, -15799, -15470, -15129, -14778, -14415, -14043, -13661,
+ -13271, -12872, -12466, -12053, -11634, -11210, -10782, -10351, -9918, -9484, -9049, -8616, -8184, -7755,
+ -7330, -6910, -6496, -6090, -5691, -5301, -4922, -4553, -4196, -3852, -3521, -3204, -2902, -2615,
+ -2343, -2087, -1847, -1624, -1417, -1226, -1051, -892, -748, -619, -504, -404, -316, -241,
+ -175, -92};
+#else
+#define LowDelayShapes_n960_N320 NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N480[780] = {
+ -4, -8, -11, -13, -16, -20, -24, -28, -33, -38, -44, -50, -57, -64,
+ -72, -81, -90, -100, -110, -121, -133, -146, -159, -173, -187, -202, -218, -235,
+ -252, -270, -289, -308, -328, -349, -370, -392, -415, -438, -462, -486, -511, -537,
+ -563, -589, -616, -643, -671, -699, -728, -757, -786, -815, -845, -875, -905, -935,
+ -965, -996, -1026, -1056, -1087, -1117, -1147, -1177, -1207, -1236, -1266, -1295, -1323, -1352,
+ -1380, -1407, -1434, -1461, -1486, -1512, -1537, -1561, -1584, -1607, -1629, -1650, -1670, -1690,
+ -1709, -1726, -1743, -1759, -1774, -1788, -1801, -1813, -1824, -1834, -1842, -1850, -1856, -1861,
+ -1865, -1868, -1870, -1870, -1869, -1867, -1863, -1858, -1852, -1845, -1836, -1826, -1814, -1801,
+ -1786, -1770, -1753, -1734, -1713, -1691, -1668, -1643, -1616, -1588, -1558, -1527, -1494, -1459,
+ -1422, -1384, -1344, -1302, -1259, -1213, -1166, -1117, -1066, -1013, -959, -902, -843, -783,
+ -720, -655, -588, -519, -448, -374, -299, -221, -141, -58, 27, 114, 203, 295,
+ 389, 486, 585, 687, 791, 898, 1007, 1119, 1234, 1351, 1471, 1593, 1718, 1846,
+ 1976, 2109, 2244, 2382, 2523, 2667, 2813, 2961, 3113, 3266, 3423, 3582, 3743, 3907,
+ 4073, 4241, 4412, 4585, 4760, 4938, 5117, 5299, 5483, 5668, 5855, 6045, 6235, 6428,
+ 6622, 6817, 7013, 7211, 7410, 7610, 7811, 8012, 8215, 8417, 8621, 8824, 9028, 9232,
+ 9436, 9639, 9843, 10045, 10248, 10449, 10650, 10850, 11048, 11246, 11442, 11636, 11829, 12020,
+ 12209, 12396, 12581, 12763, 12944, 13121, 13296, 13468, 13638, 13804, 13967, 14127, 14284, 14437,
+ 14586, 14732, 14875, 15014, 15148, 15280, 15407, 15530, 15649, 15764, 15875, 15981, 16084, 16183,
+ 16277, 16367, 16453, 16535, 16612, 16686, 16755, 16821, 16882, 16940, 16993, 17043, 17089, 17131,
+ 17170, 17205, 17237, 17265, 17291, 17313, 17331, 17348, 17361, 17371, 17379, 17385, 17388, 17389,
+ 17388, 17385, 17380, 17374, 17366, 17356, 17345, 17333, 17320, 17306, 17292, 17276, 17260, 17243,
+ 17226, 17209, 17191, 17174, 17157, 17142, 17128, 17108, 17089, 17071, 17053, 17036, 17019, 17003,
+ 16988, 16973, 16959, 16946, 16933, 16920, 16908, 16897, 16886, 16875, 16865, 16856, 16846, 16838,
+ 16829, 16821, 16814, 16806, 16799, 16793, 16786, 16780, 16775, 16769, 16764, 16759, 16755, 16751,
+ 16747, 16743, 16739, 16736, 16733, 16730, 16727, 16725, 16722, 16720, 16718, 16717, 16715, 16714,
+ 16712, 16711, 16711, 16710, 16709, 16709, 16708, 16708, 16708, 16708, 16708, 16708, 16709, 16709,
+ 16710, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, 16718, 16719, 16720, 16721, 16722,
+ 16724, 16725, 16726, 16727, 16728, 16730, 16731, 16732, 16733, 16734, 16736, 16737, 16738, 16739,
+ 16740, 16741, 16742, 16743, 16744, 16744, 16745, 16746, 16747, 16747, 16748, 16748, 16749, 16750,
+ 16750, 16750, 16751, 16751, 16751, 16752, 16752, 16752, 16753, 16753, 16753, 16753, 16753, 16754,
+ 16754, 16754, 16755, 16755, 16755, 16756, 16756, 16757, 16757, 16758, 16759, 16759, 16760, 16761,
+ 16762, 16763, 16765, 16766, 16767, 16769, 16770, 16772, 16774, 16776, 16778, 16780, 16782, 16785,
+ 16787, 16790, 16793, 16796, 16799, 16802, 16805, 16809, 16812, 16816, 16820, 16824, 16828, 16832,
+ 16836, 16840, 16845, 16849, 16854, 16858, 16863, 16868, 16873, 16878, 16883, 16888, 16893, 16898,
+ 16903, 16908, 16914, 16919, -16924, -16929, -16934, -16940, -16945, -16950, -16955, -16960, -16965, -16970,
+ -16975, -16980, -16984, -16989, -16994, -16998, -17003, -17007, -17011, -17015, -17020, -17023, -17027, -17031,
+ -17035, -17038, -17041, -17045, -17048, -17051, -17053, -17056, -17059, -17061, -17064, -17066, -17068, -17070,
+ -17072, -17074, -17075, -17077, -17078, -17080, -17081, -17082, -17083, -17084, -17085, -17086, -17086, -17087,
+ -17088, -17088, -17089, -17089, -17089, -17090, -17090, -17090, -17091, -17091, -17091, -17091, -17092, -17092,
+ -17092, -17092, -17093, -17093, -17093, -17094, -17094, -17094, -17095, -17095, -17096, -17097, -17097, -17098,
+ -17099, -17099, -17100, -17101, -17102, -17103, -17104, -17105, -17106, -17107, -17108, -17109, -17110, -17111,
+ -17113, -17114, -17115, -17116, -17118, -17119, -17120, -17121, -17123, -17124, -17125, -17126, -17127, -17129,
+ -17130, -17131, -17132, -17133, -17133, -17134, -17135, -17136, -17136, -17137, -17137, -17137, -17137, -17137,
+ -17137, -17137, -17137, -17136, -17136, -17135, -17134, -17133, -17132, -17130, -17129, -17127, -17125, -17123,
+ -17120, -17118, -17115, -17112, -17109, -17105, -17102, -17098, -17094, -17089, -17085, -17080, -17075, -17069,
+ -17063, -17057, -17051, -17044, -17037, -17030, -17022, -17014, -17005, -16997, -16987, -16978, -16967, -16957,
+ -16946, -16934, -16922, -16910, -16897, -16883, -16869, -16855, -16840, -16824, -16808, -16791, -16773, -16755,
+ -16736, -16717, -16690, -16663, -16637, -16609, -16581, -16550, -16518, -16484, -16448, -16409, -16369, -16326,
+ -16280, -16232, -16181, -16127, -16070, -16010, -15947, -15880, -15810, -15736, -15658, -15577, -15491, -15402,
+ -15308, -15210, -15108, -15001, -14890, -14775, -14655, -14530, -14401, -14267, -14128, -13985, -13837, -13685,
+ -13528, -13367, -13201, -13030, -12855, -12676, -12493, -12306, -12114, -11919, -11720, -11517, -11311, -11102,
+ -10889, -10674, -10455, -10234, -10010, -9784, -9556, -9327, -9095, -8862, -8628, -8393, -8157, -7921,
+ -7684, -7448, -7211, -6976, -6741, -6507, -6274, -6042, -5813, -5585, -5360, -5137, -4917, -4700,
+ -4487, -4276, -4070, -3867, -3668, -3474, -3284, -3099, -2919, -2744, -2574, -2410, -2251, -2097,
+ -1949, -1807, -1671, -1540, -1415, -1297, -1184, -1077, -976, -881, -791, -707, -629, -556,
+ -489, -427, -369, -317, -269, -226, -188, -151, -114, -59};
+#else
+#define LowDelayShapes_n960_N480 NULL
+#endif
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N40_5ms[70] = {
+ 29, 112, 280, 563, 991, 1590, 2380, 3377, 4587, 6006, 7624, 9416, 11353, 13393,
+ 15490, 17595, 19657, 21624, 23450, 25092, 26519, 27707, 28645, 29332, 29783, 30021, 30083, 30008,
+ 29840, 29625, 29408, 29214, 29077, 28993, 28956, 28961, 29000, 29068, 29156, 29256, -29361, -29462,
+ -29551, -29620, -29661, -29666, -29628, -29542, -29403, -29209, -28923, -28521, -27962, -27210, -26234, -25014,
+ -23541, -21819, -19874, -17743, -15481, -13149, -10820, -8571, -6479, -4611, -3020, -1753, -842, -284};
+#else
+#define LowDelayShapes_n960_N40_5ms NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N80_5ms[140] = {
+ 13, 31, 60, 102, 161, 239, 339, 464, 615, 795, 1006, 1251, 1530, 1845,
+ 2198, 2588, 3015, 3481, 3983, 4520, 5092, 5697, 6331, 6992, 7677, 8382, 9104, 9838,
+ 10580, 11326, 12071, 12811, 13540, 14255, 14951, 15624, 16270, 16885, 17466, 18010, 18515, 18978,
+ 19399, 19775, 20106, 20393, 20636, 20836, 20995, 21115, 21199, 21250, 21271, 21266, 21239, 21194,
+ 21134, 21064, 20987, 20908, 20836, 20757, 20688, 20630, 20581, 20542, 20513, 20491, 20478, 20473,
+ 20475, 20483, 20497, 20517, 20541, 20568, 20600, 20633, 20669, 20706, -20743, -20780, -20816, -20850,
+ -20881, -20910, -20934, -20954, -20968, -20977, -20979, -20973, -20960, -20938, -20908, -20868, -20819, -20761,
+ -20692, -20613, -20508, -20389, -20248, -20080, -19883, -19653, -19387, -19083, -18738, -18351, -17920, -17444,
+ -16923, -16358, -15749, -15099, -14410, -13687, -12933, -12154, -11353, -10537, -9712, -8884, -8060, -7246,
+ -6450, -5679, -4938, -4235, -3574, -2959, -2397, -1889, -1441, -1055, -732, -474, -277, -138};
+#else
+#define LowDelayShapes_n960_N80_5ms NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N120_5ms[210] = {
+ 9, 17, 28, 44, 65, 91, 123, 161, 208, 262, 325, 398, 480, 572,
+ 676, 791, 918, 1057, 1209, 1374, 1552, 1744, 1950, 2169, 2402, 2648, 2908, 3181,
+ 3468, 3767, 4078, 4402, 4736, 5081, 5437, 5801, 6174, 6554, 6942, 7335, 7732, 8134,
+ 8538, 8943, 9349, 9755, 10159, 10560, 10957, 11349, 11735, 12114, 12485, 12846, 13198, 13539,
+ 13868, 14184, 14487, 14776, 15051, 15311, 15555, 15784, 15997, 16194, 16374, 16538, 16686, 16818,
+ 16935, 17036, 17123, 17195, 17254, 17299, 17333, 17355, 17366, 17368, 17361, 17347, 17325, 17297,
+ 17265, 17228, 17189, 17147, 17104, 17061, 17024, 16979, 16938, 16901, 16867, 16837, 16811, 16788,
+ 16768, 16752, 16739, 16729, 16722, 16718, 16716, 16717, 16720, 16726, 16734, 16743, 16755, 16768,
+ 16782, 16798, 16815, 16833, 16852, 16871, 16891, 16911, -16931, -16952, -16972, -16991, -17010, -17028,
+ -17045, -17061, -17076, -17090, -17101, -17111, -17119, -17125, -17128, -17129, -17127, -17123, -17116, -17106,
+ -17092, -17076, -17056, -17033, -17006, -16976, -16942, -16905, -16864, -16820, -16760, -16698, -16630, -16553,
+ -16467, -16370, -16263, -16144, -16013, -15868, -15710, -15537, -15349, -15146, -14927, -14693, -14442, -14175,
+ -13891, -13591, -13276, -12944, -12597, -12236, -11862, -11474, -11074, -10664, -10244, -9816, -9380, -8938,
+ -8492, -8043, -7592, -7141, -6692, -6247, -5807, -5374, -4949, -4534, -4131, -3741, -3365, -3005,
+ -2662, -2337, -2030, -1744, -1478, -1234, -1012, -814, -638, -486, -357, -250, -164, -95};
+#else
+#define LowDelayShapes_n960_N120_5ms NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N160_5ms[280] = {
+ 13, 23, 36, 52, 73, 98, 128, 163, 205, 253, 308, 371, 441, 520,
+ 608, 705, 812, 929, 1056, 1195, 1344, 1505, 1678, 1863, 2060, 2270, 2493, 2729,
+ 2978, 3241, 3516, 3805, 4108, 4424, 4753, 5095, 5450, 5818, 6198, 6591, 6995, 7411,
+ 7839, 8277, 8725, 9184, 9651, 10128, 10612, 11104, 11603, 12108, 12618, 13133, 13653, 14175,
+ 14700, 15226, 15754, 16281, 16808, 17334, 17857, 18376, 18892, 19403, 19909, 20408, 20901, 21385,
+ 21861, 22328, 22784, 23231, 23666, 24089, 24500, 24898, 25283, 25654, 26011, 26354, 26681, 26994,
+ 27291, 27572, 27838, 28089, 28323, 28541, 28744, 28931, 29103, 29259, 29401, 29528, 29640, 29738,
+ 29823, 29895, 29955, 30002, 30038, 30063, 30078, 30083, 30080, 30068, 30049, 30023, 29991, 29953,
+ 29911, 29865, 29815, 29763, 29708, 29653, 29597, 29541, 29496, 29437, 29381, 29329, 29280, 29235,
+ 29194, 29156, 29122, 29091, 29064, 29039, 29018, 29000, 28986, 28974, 28964, 28958, 28954, 28953,
+ 28954, 28958, 28964, 28972, 28982, 28994, 29007, 29023, 29040, 29058, 29078, 29099, 29121, 29144,
+ 29168, 29192, 29218, 29243, 29269, 29295, -29322, -29348, -29374, -29400, -29425, -29450, -29474, -29498,
+ -29520, -29541, -29561, -29580, -29597, -29613, -29627, -29639, -29649, -29657, -29663, -29667, -29668, -29667,
+ -29663, -29657, -29647, -29635, -29620, -29602, -29580, -29556, -29528, -29496, -29462, -29424, -29382, -29337,
+ -29288, -29236, -29181, -29122, -29041, -28964, -28880, -28788, -28688, -28579, -28460, -28332, -28193, -28042,
+ -27879, -27705, -27517, -27315, -27100, -26871, -26627, -26369, -26095, -25806, -25501, -25180, -24844, -24492,
+ -24123, -23739, -23339, -22924, -22493, -22048, -21588, -21114, -20627, -20128, -19616, -19094, -18561, -18018,
+ -17467, -16907, -16341, -15769, -15192, -14611, -14028, -13442, -12857, -12272, -11689, -11109, -10533, -9963,
+ -9400, -8846, -8300, -7765, -7241, -6730, -6232, -5749, -5282, -4830, -4396, -3979, -3581, -3202,
+ -2843, -2505, -2188, -1893, -1620, -1369, -1141, -936, -753, -593, -454, -336, -237, -155};
+#else
+#define LowDelayShapes_n960_N160_5ms NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N240_5ms[420] = {
+ 10, 15, 21, 27, 36, 45, 56, 69, 83, 100, 118, 138, 161, 186,
+ 214, 244, 276, 312, 350, 392, 436, 484, 535, 590, 648, 710, 775, 845,
+ 918, 995, 1076, 1162, 1252, 1346, 1444, 1547, 1655, 1767, 1883, 2005, 2131, 2261,
+ 2397, 2537, 2683, 2833, 2988, 3148, 3312, 3482, 3656, 3835, 4019, 4208, 4401, 4599,
+ 4801, 5008, 5220, 5436, 5656, 5880, 6109, 6342, 6578, 6818, 7063, 7310, 7562, 7816,
+ 8074, 8335, 8598, 8865, 9134, 9405, 9679, 9955, 10233, 10513, 10794, 11076, 11360, 11645,
+ 11931, 12217, 12504, 12791, 13078, 13366, 13652, 13939, 14224, 14509, 14792, 15075, 15356, 15635,
+ 15912, 16187, 16460, 16731, 16999, 17264, 17526, 17785, 18041, 18293, 18542, 18787, 19028, 19264,
+ 19497, 19725, 19949, 20168, 20382, 20592, 20796, 20996, 21190, 21379, 21563, 21741, 21914, 22082,
+ 22243, 22399, 22550, 22695, 22834, 22967, 23095, 23216, 23332, 23443, 23548, 23647, 23740, 23828,
+ 23910, 23987, 24059, 24125, 24186, 24243, 24294, 24340, 24381, 24418, 24450, 24478, 24502, 24522,
+ 24537, 24549, 24557, 24562, 24563, 24561, 24556, 24549, 24538, 24525, 24510, 24492, 24473, 24451,
+ 24428, 24404, 24378, 24351, 24323, 24294, 24264, 24234, 24204, 24173, 24143, 24112, 24093, 24059,
+ 24027, 23997, 23968, 23940, 23914, 23889, 23865, 23842, 23821, 23801, 23783, 23765, 23749, 23734,
+ 23720, 23708, 23696, 23686, 23677, 23668, 23661, 23655, 23650, 23647, 23644, 23641, 23640, 23640,
+ 23641, 23642, 23645, 23648, 23652, 23657, 23662, 23668, 23675, 23682, 23691, 23699, 23708, 23718,
+ 23728, 23739, 23750, 23762, 23774, 23786, 23799, 23812, 23825, 23839, 23853, 23866, 23881, 23895,
+ 23909, 23923, -23938, -23952, -23966, -23980, -23994, -24008, -24022, -24036, -24049, -24062, -24075, -24088,
+ -24100, -24112, -24123, -24134, -24144, -24154, -24164, -24173, -24181, -24189, -24195, -24202, -24207, -24212,
+ -24216, -24219, -24222, -24223, -24224, -24224, -24223, -24221, -24218, -24214, -24208, -24202, -24195, -24187,
+ -24177, -24167, -24155, -24142, -24128, -24113, -24097, -24079, -24060, -24040, -24019, -23996, -23972, -23947,
+ -23921, -23893, -23864, -23834, -23802, -23769, -23721, -23681, -23638, -23592, -23543, -23492, -23438, -23380,
+ -23319, -23255, -23186, -23115, -23039, -22959, -22875, -22786, -22693, -22596, -22494, -22387, -22275, -22157,
+ -22035, -21908, -21775, -21637, -21494, -21345, -21190, -21030, -20864, -20692, -20515, -20332, -20143, -19948,
+ -19748, -19541, -19329, -19112, -18888, -18659, -18425, -18185, -17940, -17690, -17434, -17174, -16909, -16639,
+ -16365, -16087, -15804, -15518, -15228, -14934, -14637, -14337, -14034, -13728, -13420, -13109, -12797, -12483,
+ -12167, -11851, -11533, -11215, -10896, -10577, -10258, -9940, -9623, -9307, -8992, -8678, -8367, -8058,
+ -7752, -7448, -7148, -6851, -6557, -6268, -5983, -5702, -5426, -5156, -4890, -4630, -4375, -4126,
+ -3884, -3647, -3417, -3194, -2977, -2767, -2565, -2369, -2181, -2001, -1829, -1664, -1507, -1358,
+ -1218, -1085, -961, -846, -738, -639, -547, -464, -388, -320, -259, -206, -159, -124};
+#else
+#define LowDelayShapes_n960_N240_5ms NULL
+#endif
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N40_2_5ms[40] = {
+ 140, 566, 1277, 2319, 3704, 5404, 7357, 9466, 11616, 13686, 15563, 17163, 18436, 19375,
+ 20007, 20391, 20594, 20685, 20717, 20724, -20724, -20717, -20685, -20594, -20391, -20007, -19375, -18436,
+ -17163, -15563, -13686, -11616, -9466, -7357, -5404, -3704, -2319, -1277, -566, -140};
+#else
+#define LowDelayShapes_n960_N40_2_5ms NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N80_2_5ms[80] = {
+ 140, 353, 653, 1049, 1553, 2171, 2909, 3768, 4747, 5842, 7043, 8341, 9721, 11165,
+ 12655, 14170, 15688, 17188, 18649, 20051, 21376, 22610, 23739, 24756, 25656, 26436, 27099, 27650,
+ 28097, 28450, 28721, 28922, 29065, 29164, 29228, 29267, 29290, 29301, 29306, 29308, -29308, -29306,
+ -29301, -29290, -29267, -29228, -29164, -29065, -28922, -28721, -28450, -28097, -27650, -27099, -26436, -25656,
+ -24756, -23739, -22610, -21376, -20051, -18649, -17188, -15688, -14170, -12655, -11165, -9721, -8341, -7043,
+ -5842, -4747, -3768, -2909, -2171, -1553, -1049, -653, -353, -140};
+#else
+#define LowDelayShapes_n960_N80_2_5ms NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N120_2_5ms[120] = {
+ 93, 196, 328, 491, 689, 924, 1199, 1514, 1873, 2274, 2720, 3209, 3742, 4318,
+ 4934, 5588, 6277, 7000, 7750, 8526, 9321, 10132, 10953, 11780, 12606, 13427, 14237, 15032,
+ 15807, 16557, 17278, 17967, 18620, 19234, 19809, 20341, 20830, 21276, 21680, 22040, 22360, 22641,
+ 22884, 23092, 23269, 23416, 23538, 23636, 23714, 23775, 23822, 23857, 23882, 23900, 23913, 23920,
+ 23925, 23928, 23930, 23930, -23930, -23930, -23928, -23925, -23920, -23913, -23900, -23882, -23857, -23822,
+ -23775, -23714, -23636, -23538, -23416, -23269, -23092, -22884, -22641, -22360, -22040, -21680, -21276, -20830,
+ -20341, -19809, -19234, -18620, -17967, -17278, -16557, -15807, -15032, -14237, -13427, -12606, -11780, -10953,
+ -10132, -9321, -8526, -7750, -7000, -6277, -5588, -4934, -4318, -3742, -3209, -2720, -2274, -1873,
+ -1514, -1199, -924, -689, -491, -328, -196, -93};
+#else
+#define LowDelayShapes_n960_N120_2_5ms NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N160_2_5ms[160] = {
+ 70, 134, 210, 301, 407, 530, 671, 830, 1008, 1206, 1425, 1665, 1926, 2208,
+ 2512, 2837, 3183, 3550, 3937, 4343, 4768, 5211, 5670, 6143, 6631, 7131, 7642, 8161,
+ 8688, 9219, 9755, 10292, 10828, 11363, 11893, 12417, 12933, 13440, 13936, 14418, 14887, 15339,
+ 15775, 16193, 16593, 16972, 17332, 17670, 17988, 18285, 18561, 18816, 19050, 19264, 19459, 19635,
+ 19793, 19934, 20059, 20168, 20264, 20347, 20418, 20478, 20529, 20572, 20606, 20635, 20657, 20675,
+ 20689, 20700, 20708, 20713, 20718, 20720, 20722, 20723, 20724, 20724, -20724, -20724, -20723, -20722,
+ -20720, -20718, -20713, -20708, -20700, -20689, -20675, -20657, -20635, -20606, -20572, -20529, -20478, -20418,
+ -20347, -20264, -20168, -20059, -19934, -19793, -19635, -19459, -19264, -19050, -18816, -18561, -18285, -17988,
+ -17670, -17332, -16972, -16593, -16193, -15775, -15339, -14887, -14418, -13936, -13440, -12933, -12417, -11893,
+ -11363, -10828, -10292, -9755, -9219, -8688, -8161, -7642, -7131, -6631, -6143, -5670, -5211, -4768,
+ -4343, -3937, -3550, -3183, -2837, -2512, -2208, -1926, -1665, -1425, -1206, -1008, -830, -671,
+ -530, -407, -301, -210, -134, -70};
+#else
+#define LowDelayShapes_n960_N160_2_5ms NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 LowDelayShapes_n960_N240_2_5ms[240] = {
+ 47, 81, 118, 160, 207, 259, 317, 381, 452, 528, 611, 701, 799, 903,
+ 1015, 1134, 1260, 1395, 1537, 1686, 1844, 2009, 2183, 2363, 2552, 2748, 2951, 3162,
+ 3380, 3604, 3836, 4073, 4317, 4567, 4822, 5083, 5348, 5618, 5892, 6170, 6451, 6735,
+ 7022, 7311, 7601, 7892, 8185, 8477, 8769, 9060, 9350, 9639, 9926, 10209, 10491, 10768,
+ 11042, 11312, 11577, 11837, 12092, 12341, 12585, 12822, 13053, 13277, 13494, 13705, 13908, 14103,
+ 14291, 14472, 14645, 14810, 14968, 15118, 15261, 15396, 15523, 15643, 15756, 15862, 15961, 16054,
+ 16140, 16220, 16293, 16361, 16424, 16481, 16533, 16580, 16623, 16662, 16697, 16728, 16755, 16780,
+ 16802, 16821, 16837, 16851, 16864, 16874, 16883, 16891, 16897, 16902, 16907, 16910, 16913, 16915,
+ 16917, 16918, 16919, 16920, 16921, 16921, 16921, 16921, -16921, -16921, -16921, -16921, -16920, -16919,
+ -16918, -16917, -16915, -16913, -16910, -16907, -16902, -16897, -16891, -16883, -16874, -16864, -16851, -16837,
+ -16821, -16802, -16780, -16755, -16728, -16697, -16662, -16623, -16580, -16533, -16481, -16424, -16361, -16293,
+ -16220, -16140, -16054, -15961, -15862, -15756, -15643, -15523, -15396, -15261, -15118, -14968, -14810, -14645,
+ -14472, -14291, -14103, -13908, -13705, -13494, -13277, -13053, -12822, -12585, -12341, -12092, -11837, -11577,
+ -11312, -11042, -10768, -10491, -10209, -9926, -9639, -9350, -9060, -8769, -8477, -8185, -7892, -7601,
+ -7311, -7022, -6735, -6451, -6170, -5892, -5618, -5348, -5083, -4822, -4567, -4317, -4073, -3836,
+ -3604, -3380, -3162, -2951, -2748, -2552, -2363, -2183, -2009, -1844, -1686, -1537, -1395, -1260,
+ -1134, -1015, -903, -799, -701, -611, -528, -452, -381, -317, -259, -207, -160, -118,
+ -81, -47};
+#else
+#define LowDelayShapes_n960_N240_2_5ms NULL
+#endif
+
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word32 lag_win_8k[16] = {0x7fdba30b, 0x7f6eca1a, 0x7eba2e4e, 0x7dbf01e8, 0x7c7eecec, 0x7afc0879,
+ 0x7938d8eb, 0x773846e0, 0x74fd973a, 0x728c623e, 0x6fe889ee, 0x6d162fc8,
+ 0x6a19aa0b, 0x66f778a7, 0x63b43a09, 0x60549fe1};
+#else
+#define lag_win_8k NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word32 lag_win_16k[16] = {0x7ff6e7cb, 0x7fdba30b, 0x7fae3d5f, 0x7f6eca1a, 0x7f1d643a, 0x7eba2e4e,
+ 0x7e455264, 0x7dbf01e8, 0x7d277581, 0x7c7eecec, 0x7bc5aecb, 0x7afc0879,
+ 0x7a224dcf, 0x7938d8eb, 0x784009f7, 0x773846e0};
+#else
+#define lag_win_16k NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word32 lag_win_24k[16] = {0x7ffbf529, 0x7fefd569, 0x7fdba30b, 0x7fbf61e2, 0x7f9b1748, 0x7f6eca1a,
+ 0x7f3a82b8, 0x7efe4b00, 0x7eba2e4e, 0x7e6e3976, 0x7e1a7ac1, 0x7dbf01e8,
+ 0x7d5be00f, 0x7cf127c2, 0x7c7eecec, 0x7c0544d0};
+#else
+#define lag_win_24k NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word32 lag_win_32k[16] = {0x7ffdb9e3, 0x7ff6e7cb, 0x7feb8a70, 0x7fdba30b, 0x7fc7334b, 0x7fae3d5f,
+ 0x7f90c3ed, 0x7f6eca1a, 0x7f485382, 0x7f1d643a, 0x7eee00d1, 0x7eba2e4e,
+ 0x7e81f22e, 0x7e455264, 0x7e045558, 0x7dbf01e8};
+#else
+#define lag_win_32k NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word32 lag_win_48k[16] = {0x7ffefd47, 0x7ffbf529, 0x7ff6e7cb, 0x7fefd569, 0x7fe6be59, 0x7fdba30b,
+ 0x7fce8403, 0x7fbf61e2, 0x7fae3d5f, 0x7f9b1748, 0x7f85f087, 0x7f6eca1a,
+ 0x7f55a51b, 0x7f3a82b8, 0x7f1d643a, 0x7efe4b00};
+#else
+#define lag_win_48k NULL
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 lag_win_96k[16] = {0x7fffbf52, 0x7ffefd47, 0x7ffdb9e3, 0x7ffbf529, 0x7ff9af1f, 0x7ff6e7cb,
+ 0x7ff39f35, 0x7fefd569, 0x7feb8a70, 0x7fe6be59, 0x7fe17132, 0x7fdba30b,
+ 0x7fd553f5, 0x7fce8403, 0x7fc7334b, 0x7fbf61e2};
+# else
+# define lag_win_96k NULL
+# endif
+
+RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ] = {lag_win_8k, lag_win_16k, lag_win_24k, lag_win_32k, lag_win_48k, lag_win_96k};
+
+RAM_ALIGN const Word16 sqrt_table_phecu[49] = {/* used by Sqrt_l */
+ 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480,
+ 20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232,
+ 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477,
+ 27780, 28081, 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377,
+ 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511, 32767};
+
+/* First frequency bin in each subband now adjusted to include last bin *
+ * which was missed with the previous definition *
+ * 250 750 1250 2250 4250 8250 12250 16250 20250 ( 24250 ) *
+ * note that bins over 20000 are zeroed and not used */
+/* [- FB ----------------------------) (Currently limited to 20kHz)
+ * [- SWB -----------------------)
+ * [- sWB -------------------)
+ * [- WB ----------------)
+ * [- NB -----------)
+ */
+
+RAM_ALIGN const Word16 gw_len_inv_shift_fx[MAX_LGW] = {/* Q0 */
+ 1 - 1 /*/1/2*/, 1 - 1, 2 - 1 /*1/4*/,
+ 3 - 1 /*1/8*/, 4 - 1 /*1/16*/, 4 - 1,
+ 4 - 1, 4 - 1, 4 - 1};
+RAM_ALIGN const Word16 gwlpr_fx[MAX_LGW + 1] = {
+ 1,
+ 3 * QUOT_LPR_LTR,
+ 5 * QUOT_LPR_LTR,
+ 9 * QUOT_LPR_LTR,
+ 17 * QUOT_LPR_LTR,
+ 33 * QUOT_LPR_LTR,
+ 49 * QUOT_LPR_LTR,
+ 65 * QUOT_LPR_LTR,
+ 81 * QUOT_LPR_LTR,
+ 97 * QUOT_LPR_LTR}; /* frequency group start bins for transient analysis */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ /* puretone_ana compressed ATH bandborder weights */
+RAM_ALIGN const Word16 scATHFx[MAX_LGW - 2] = { 14924 , 30499 , 31886 , 32767 , 29770 , 25417 , 16384 };
+ /* 0.455444335937500 0.930755615234375 0.973083496093750 0.999969482421875 0.908508300781250 0.775665283203125 0.5*/
+#endif
+
+RAM_ALIGN const Word16 e_tot_headroom[5] = {3, 3, 4, 4, 4}; /* smallest head room to use for each fs */
+
+
+
+RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[5] = {4077, 8283, 12489, 16698,
+ 25109}; /* Q11 Mantissa of scale to use for each fs */
+
+RAM_ALIGN const Word16 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, 20675, 19745, 18856, 18007, 17197, 16423,
+ 8211, 4106, 2053, 1026, 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0};
+RAM_ALIGN const Word16 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, 23198, 22410, 21650, 20915, 20205, 19519,
+ 9759, 4880, 2440, 1220, 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, 0};
+
+#ifdef PLC2_FADEOUT_IN_MS
+#if PLC2_FADEOUT_IN_MS == 0
+#ifndef CR8_A_PLC_FADEOUT_TUNING
+/*/ default setting only requieres two tables */
+RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 2] = {
+ NULL,
+ POW_ATT_TABLE1 /*1 0.3dB steps */,
+ POW_ATT_TABLE0 /*2 0.4 dB steps*/,
+};
+#endif
+
+#else /* PLC2_FADEOUT_IN_MS == 0 */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+RAM_ALIGN const Word16 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = {
+ 32767,
+ 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, /* 9 times .3dB steps , 14 6 dB steps, 7 muted steps */
+ 12007, 6003, 3002, 1501, 750, 375, 188, 94, 47, 23, 12, 6, 3, 1,
+ 0, 0, 0, 0, 0, 0, 0 };
+
+RAM_ALIGN const Word16 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] =
+{ 32767,
+ 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, /* 9 times .4dB steps , 14 6 dB steps, 7 muted steps */
+ 10825, 5413, 2706, 1353, 677, 338, 169, 85, 42, 21, 11, 5, 3, 1,
+ 0, 0,0,0,0,0,0 };
+#endif
+
+RAM_ALIGN const Word16 POW_ATT_TABLE_p3x8_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, 3216, 1608, 804, 402, 201, 101,
+ 50, 25, 13, 6, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0};
+RAM_ALIGN const Word16 POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 11869, 5935, 2967, 1484, 742, 371, 185, 93,
+ 46, 23, 12, 6, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
+
+RAM_ALIGN const Word16 POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31656, 30581, 29543, 14772, 7386, 3693, 1847, 923, 462, 231, 115, 58, 29, 14, 7,
+ 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+RAM_ALIGN const Word16 POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31293, 29885, 28540, 14270, 7135, 3568, 1784, 892, 446, 223, 111, 56, 28, 14, 7,
+ 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+RAM_ALIGN const Word16 POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31656, 15828, 7914, 3957, 1979, 989, 495, 247, 124, 62, 31, 15, 8, 4, 2,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+RAM_ALIGN const Word16 POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 31293, 15647, 7823, 3912, 1956, 978, 489, 244, 122, 61, 31, 15, 8, 4, 2,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+RAM_ALIGN const Word16 POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+RAM_ALIGN const Word16 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = {
+ 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */
+/* POW_ATT_TABLES[ind] is used after teh initial gain==1.0 no energy muting phase */
+RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 24 / 2] =
+{ NULL,
+/*0.3dB col , 0.4dB col */
+/* 1*/POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6, /* 0 0.3dB, 16 6dB, 14mute */ /* 0.4dB version */ /* old short mute tabs */
+/* 3*/POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* 1 0.3dB, 15 6dB ,14mute */ /* 0.4dB version */
+/* 5*/POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* 3 0.3dB, 15 6dB , 12 mute */ /* 0.4dB version */
+/* 7*/POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* 7 0.3dB, 15 6dB , 8 mute */ /* 0.4dB version */
+/* 9*/POW_ATT_TABLE_p3x9_14_7, POW_ATT_TABLE_p4x9_14_7, /* 9 0.3dB, 14 6dB , 7 mute */ /* 0.4dB version */ /* opt 120 ms */
+/*11*/POW_ATT_TABLE1, POW_ATT_TABLE0, /* 15 0.3dB, 14 6dB , 1 mute */ /* 0.4dB version */ /* 3GPP original/default curves */
+};
+
+/* PLC_FADEOUT_TUNING, extended table nominal muting phases from 30 ms to 140 ms */
+RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3] = {
+/* burst_att_thresh indicates when muting POW_ATT_TABLE[att_per_frame_idx] should be used first time it is 1.0 though */
+/* burst_att_thresh ==2 --> gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/
+/* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/
+/* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */
+
+/* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */
+{ 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */
+{ 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */
+{ 3, 3, 1 + 3 + 1 }, /* 50 ms, 0.3 dB delta att in slow mutephase */
+{ 3, 4, 1 + 4 + 1}, /* 60 ms, 0.3 dB delta att in slow mutephase */
+{ 5, 4, 3 + 4 + 1 }, /* 70 ms, 0.3 dB delta att in slow mutephase */
+{ 5, 5, 3 + 5 + 1 }, /* 80 ms, 0.3 dB delta att in slow mutephase */
+{ 7, 5, 7 + 5 }, /* 90 ms, 0.3 dB delta att in slow mutephase */
+{ 7, 5, 7 + 5 + 1}, /* 100 ms, 0.3 dB delta att in slow mutephase */
+{ 9, 5, 9 + 5 }, /* 110 ms, 0.3 dB delta att in slow mutephase */
+{ 9, 5, 9 + 5 + 1}, /* 120 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=1 */
+{ 11, 5, 15 + 5 },/* 130 ms, 0.3 dB delta att in slow mutephase */
+{ 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */
+};
+/*fade_scheme_tab_fx[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */
+/*fade_scheme_tab_fx[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */
+/*fade_scheme_tab_fx[ind][2] is beta_mute_thr, the location of the start of final attenuation */
+
+#else
+RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 10] = {
+ NULL,
+ POW_ATT_TABLE1,
+ POW_ATT_TABLE0,
+ /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */
+ POW_ATT_TABLE_p3x8_6,
+ POW_ATT_TABLE_p4x8_6,
+ /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */
+ POW_ATT_TABLE_p3x4_6,
+ POW_ATT_TABLE_p4x4_6,
+ /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */
+ POW_ATT_TABLE_p3x2_6,
+ POW_ATT_TABLE_p4x2_6,
+ /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */
+ POW_ATT_TABLE_p3x1_6,
+ POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */
+};
+#endif
+
+#endif /* PLC2_FADEOUT_IN_MS == 0 */
+
+#else /* PLC2_FADEOUT_IN_MS */
+RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 2] = {
+ NULL,
+ POW_ATT_TABLE1 /*1 .3dB steps */,
+ POW_ATT_TABLE0 /*2 .4 dB steps*/,
+};
+#endif /* PLC2_FADEOUT_IN_MS */
+
+RAM_ALIGN const Word16 sin_quarterQ15_fx[256 + 1] = {
+ 0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, 2009, 2210, 2411, 2611, 2811, 3012,
+ 3212, 3412, 3612, 3812, 4011, 4211, 4410, 4609, 4808, 5007, 5205, 5404, 5602, 5800, 5998, 6195,
+ 6393, 6590, 6787, 6983, 7180, 7376, 7571, 7767, 7962, 8157, 8351, 8546, 8740, 8933, 9127, 9319,
+ 9512, 9704, 9896, 10088, 10279, 10469, 10660, 10850, 11039, 11228, 11417, 11605, 11793, 11980, 12167, 12354,
+ 12540, 12725, 12910, 13095, 13279, 13463, 13646, 13828, 14010, 14192, 14373, 14553, 14733, 14912, 15091, 15269,
+ 15447, 15624, 15800, 15976, 16151, 16326, 16500, 16673, 16846, 17018, 17190, 17361, 17531, 17700, 17869, 18037,
+ 18205, 18372, 18538, 18703, 18868, 19032, 19195, 19358, 19520, 19681, 19841, 20001, 20160, 20318, 20475, 20632,
+ 20788, 20943, 21097, 21251, 21403, 21555, 21706, 21856, 22006, 22154, 22302, 22449, 22595, 22740, 22884, 23028,
+ 23170, 23312, 23453, 23593, 23732, 23870, 24008, 24144, 24279, 24414, 24548, 24680, 24812, 24943, 25073, 25202,
+ 25330, 25457, 25583, 25708, 25833, 25956, 26078, 26199, 26320, 26439, 26557, 26674, 26791, 26906, 27020, 27133,
+ 27246, 27357, 27467, 27576, 27684, 27791, 27897, 28002, 28106, 28209, 28311, 28411, 28511, 28610, 28707, 28803,
+ 28899, 28993, 29086, 29178, 29269, 29359, 29448, 29535, 29622, 29707, 29792, 29875, 29957, 30038, 30118, 30196,
+ 30274, 30350, 30425, 30499, 30572, 30644, 30715, 30784, 30853, 30920, 30986, 31050, 31114, 31177, 31238, 31298,
+ 31357, 31415, 31471, 31527, 31581, 31634, 31686, 31737, 31786, 31834, 31881, 31927, 31972, 32015, 32058, 32099,
+ 32138, 32177, 32214, 32251, 32286, 32319, 32352, 32383, 32413, 32442, 32470, 32496, 32522, 32546, 32568, 32590,
+ 32610, 32629, 32647, 32664, 32679, 32693, 32706, 32718, 32729, 32738, 32746, 32753, 32758, 32762, 32766, 32767,
+ 32767};
+
+/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing (window 11) */
+/* 3+3ms tapering for the hamming parts */
+/* temporary ROM solution */
+/* alternatively use values from a single 48 kHz table */
+
+/* 3ms rising tapering part @48 kHZ */
+/* only quarter sine hamming part is actually used by the C-function windowing_fx */
+/* OPT: store only one table at 48 or 96 kHz */
+/* OPT2: for this to work one must switch to 'periodic' instead of used 'symetric' windows, *
+ * the different windows are just sub-sampled windows of a 96kHz window */
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 PhECU_whr16ms_NB_Q15[Lprot_hamm_len2_8k] = {/* From matlab */
+ 2621, 2750, 3135, 3769, 4641, 5736,
+ 7036, 8519, 10158, 11926, 13793, 15727,
+ 17695, 19662, 21596, 23463, 25231, 26871,
+ 28353, 29653, 30749, 31621, 32254, 32639};
+#else
+#define PhECU_whr16ms_NB_Q15 NULL
+#endif
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 PhECU_whr16ms_WB_Q15[Lprot_hamm_len2_16k] = {/* From matlab */
+ 2621, 2654, 2750, 2911, 3135, 3421, 3769,
+ 4176, 4641, 5162, 5736, 6362, 7036, 7756,
+ 8519, 9320, 10158, 11028, 11926, 12850, 13793,
+ 14754, 15727, 16709, 17695, 18681, 19662, 20635,
+ 21596, 22540, 23463, 24361, 25231, 26069, 26871,
+ 27633, 28353, 29027, 29653, 30228, 30749, 31214,
+ 31621, 31968, 32254, 32478, 32639, 32736};
+#else
+#define PhECU_whr16ms_WB_Q15 NULL
+#endif
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 PhECU_whr16ms_sWB_Q15[Lprot_hamm_len2_24k] =
+ {/* From matlab */
+ 2621, 2636, 2679, 2750, 2850, 2979, 3135, 3319, 3530, 3769, 4034, 4325, 4641, 4982, 5347,
+ 5736, 6148, 6582, 7036, 7511, 8006, 8519, 9049, 9596, 10158, 10735, 11324, 11926, 12539, 13162,
+ 13793, 14432, 15077, 15727, 16381, 17037, 17695, 18352, 19008, 19662, 20312, 20957, 21596, 22227, 22850,
+ 23463, 24065, 24655, 25231, 25794, 26340, 26871, 27384, 27878, 28353, 28808, 29242, 29653, 30042, 30407,
+ 30749, 31065, 31356, 31621, 31859, 32070, 32254, 32411, 32539, 32639, 32711, 32754};
+#else
+#define PhECU_whr16ms_sWB_Q15 NULL
+#endif
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 PhECU_whr16ms_SWB_Q15[Lprot_hamm_len2_32k] =
+ {/* From matlab */
+ 2621, 2630, 2654, 2694, 2750, 2823, 2911, 3015, 3135, 3270, 3421, 3588, 3769, 3965, 4176, 4401,
+ 4641, 4894, 5162, 5442, 5736, 6043, 6362, 6693, 7036, 7391, 7756, 8132, 8519, 8915, 9320, 9735,
+ 10158, 10589, 11028, 11474, 11926, 12385, 12850, 13319, 13793, 14272, 14754, 15239, 15727, 16217, 16709, 17202,
+ 17695, 18188, 18681, 19172, 19662, 20150, 20635, 21118, 21596, 22070, 22540, 23004, 23463, 23916, 24361, 24800,
+ 25231, 25654, 26069, 26475, 26871, 27257, 27633, 27999, 28353, 28696, 29027, 29347, 29653, 29947, 30228, 30495,
+ 30749, 30988, 31214, 31424, 31621, 31802, 31968, 32119, 32254, 32374, 32478, 32567, 32639, 32695, 32736, 32760};
+#else
+#define PhECU_whr16ms_SWB_Q15 NULL
+#endif
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 PhECU_whr16ms_FB_Q15[Lprot_hamm_len2_48k] =
+ {/* From matlab */
+ 2621, 2625, 2636, 2654, 2679, 2711, 2750, 2797, 2850, 2911, 2979, 3053, 3135, 3224, 3319, 3421,
+ 3530, 3646, 3769, 3898, 4034, 4176, 4325, 4480, 4641, 4808, 4982, 5162, 5347, 5539, 5736, 5939,
+ 6148, 6362, 6582, 6806, 7036, 7271, 7511, 7756, 8006, 8260, 8519, 8782, 9049, 9320, 9596, 9875,
+ 10158, 10445, 10735, 11028, 11324, 11624, 11926, 12232, 12539, 12850, 13162, 13477, 13793, 14112, 14432, 14754,
+ 15077, 15402, 15727, 16054, 16381, 16709, 17037, 17366, 17695, 18024, 18352, 18681, 19008, 19336, 19662, 19988,
+ 20312, 20635, 20957, 21277, 21596, 21913, 22227, 22540, 22850, 23158, 23463, 23765, 24065, 24361, 24655, 24945,
+ 25231, 25514, 25794, 26069, 26340, 26608, 26871, 27129, 27384, 27633, 27878, 28118, 28353, 28583, 28808, 29027,
+ 29242, 29450, 29653, 29850, 30042, 30228, 30407, 30581, 30749, 30910, 31065, 31214, 31356, 31491, 31621, 31743,
+ 31859, 31968, 32070, 32166, 32254, 32336, 32411, 32478, 32539, 32593, 32639, 32678, 32711, 32736, 32754, 32764};
+#else
+#define PhECU_whr16ms_FB_Q15 NULL
+#endif
+
+/* initial 2ms for preTda is the LD-MDCT analysis window times the centered inverse whr window */
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_128_pre_Q14[16] = {-12, -34, -74, -135, -219, -327, -459, -610,
+ -776, -949, -1125, -1295, -1451, -1587, -1696, -1771};
+#else
+#define PhECU_preTdaFx16ms_128_pre_Q14 NULL
+#endif
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_256_pre_Q14[32] = {
+ -8, -16, -27, -42, -63, -87, -117, -154, -196, -244, -299, -358, -424, -495, -570, -650,
+ -733, -818, -906, -993, -1082, -1168, -1253, -1336, -1414, -1488, -1556, -1617, -1671, -1718, -1755, -1784};
+#else
+#define PhECU_preTdaFx16ms_256_pre_Q14 NULL
+#endif
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_384_pre_Q14[48] = {
+ -6, -12, -18, -25, -34, -45, -59, -74, -92, -112, -135, -160, -188, -219, -253, -289,
+ -328, -369, -413, -459, -507, -557, -610, -663, -719, -775, -833, -891, -950, -1008, -1067, -1125,
+ -1183, -1239, -1295, -1349, -1401, -1451, -1499, -1545, -1587, -1627, -1663, -1696, -1725, -1750, -1771, -1788};
+#else
+#define PhECU_preTdaFx16ms_384_pre_Q14 NULL
+#endif
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_512_pre_Q14[64] = {
+ -5, -9, -13, -18, -24, -31, -38, -47, -57, -68, -81, -94, -109, -126, -144, -164,
+ -185, -207, -232, -257, -284, -313, -343, -374, -407, -441, -477, -513, -551, -590, -630, -670,
+ -712, -754, -797, -840, -884, -927, -972, -1016, -1059, -1104, -1147, -1190, -1232, -1274, -1316, -1356,
+ -1395, -1433, -1470, -1505, -1539, -1572, -1602, -1632, -1659, -1684, -1707, -1728, -1747, -1763, -1777, -1789};
+#else
+#define PhECU_preTdaFx16ms_512_pre_Q14 NULL
+#endif
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_768_pre_Q14[96] = {
+ -4, -8, -11, -13, -15, -19, -23, -27, -32, -37, -43, -48, -55, -62, -70, -78,
+ -87, -97, -107, -117, -129, -141, -154, -168, -181, -196, -211, -228, -244, -261, -280, -298,
+ -318, -338, -358, -380, -402, -424, -447, -471, -495, -520, -545, -570, -596, -623, -650, -677,
+ -705, -733, -761, -789, -818, -847, -876, -905, -934, -964, -993, -1022, -1052, -1082, -1111, -1140,
+ -1169, -1197, -1226, -1254, -1281, -1309, -1336, -1362, -1388, -1415, -1439, -1464, -1488, -1511, -1534, -1556,
+ -1577, -1598, -1617, -1636, -1655, -1671, -1688, -1703, -1718, -1731, -1744, -1755, -1766, -1776, -1784, -1791};
+#else
+#define PhECU_preTdaFx16ms_768_pre_Q14 NULL
+#endif
+
+/* ROM OPT compute it runtime based on MDCT win and tabled inverse hamming sections */
+/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing */
+/* OPT2 can be reduced to 14.25 ms, due to 1.75 ms trailing zeroes */
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_NB_Q14[128] = {
+ -22591, -21465, -18295, -14331, -10544, -7321, -4690, -2561, -811, 662, 1942, 3090, 4148, 5146, 6107, 7043,
+ 7961, 8868, 9761, 10640, 11502, 12345, 13164, 13959, 14731, 15423, 15970, 16374, 16642, 16789, 16837, 16810,
+ 16735, 16637, 16537, 16441, 16366, 16307, 16263, 16230, 16206, 16190, 16181, 16177, 16178, 16182, 16188, 16196,
+ 16203, 16209, 16214, 16218, 16219, 16221, 16222, 16226, 16230, 16238, 16251, 16267, 16287, 16312, 16339, 16369,
+ 16399, 16429, 16456, 16481, 16502, 16518, 16531, 16539, 16544, 16547, 16548, 16550, 16552, 16556, 16561, 16567,
+ 16575, 16582, 16588, 16592, 16593, 16589, 16580, 16564, 16540, 16506, 16461, 16402, 16327, 16232, 16095, 15907,
+ 15641, 15272, 14775, 14130, 13325, 12361, 11251, 10017, 8694, 7354, 6057, 4825, 3684, 2665, 1795, 1095,
+ 575, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+#else
+#define PhECU_preTdaFx16ms_NB_Q14 NULL
+#endif
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_WB_Q14[256] = {
+ -22528, -22351, -21532, -20186, -18475, -16565, -14596, -12673, -10858, -9181, -7654, -6277, -5037, -3923, -2914,
+ -2001, -1169, -405, 303, 961, 1580, 2166, 2725, 3263, 3781, 4285, 4778, 5262, 5739, 6211,
+ 6677, 7140, 7601, 8059, 8514, 8968, 9419, 9868, 10314, 10756, 11195, 11630, 12060, 12486, 12907,
+ 13322, 13733, 14137, 14537, 14917, 15263, 15573, 15847, 16085, 16286, 16454, 16587, 16689, 16763, 16810,
+ 16833, 16836, 16822, 16795, 16757, 16712, 16663, 16612, 16565, 16511, 16464, 16421, 16383, 16350, 16321,
+ 16295, 16272, 16253, 16237, 16223, 16211, 16201, 16194, 16187, 16183, 16180, 16178, 16177, 16178, 16179,
+ 16181, 16184, 16187, 16190, 16194, 16198, 16201, 16204, 16208, 16210, 16213, 16215, 16217, 16218, 16219,
+ 16220, 16221, 16222, 16222, 16223, 16225, 16227, 16229, 16232, 16236, 16241, 16247, 16255, 16262, 16272,
+ 16282, 16293, 16305, 16319, 16332, 16347, 16361, 16376, 16391, 16407, 16422, 16436, 16450, 16463, 16475,
+ 16487, 16497, 16506, 16514, 16522, 16528, 16533, 16537, 16541, 16543, 16545, 16546, 16547, 16548, 16549,
+ 16550, 16550, 16551, 16553, 16555, 16557, 16560, 16563, 16566, 16569, 16573, 16577, 16580, 16584, 16587,
+ 16589, 16592, 16593, 16593, 16593, 16591, 16588, 16583, 16577, 16569, 16559, 16547, 16532, 16516, 16496,
+ 16474, 16448, 16418, 16385, 16347, 16305, 16258, 16205, 16134, 16054, 15960, 15849, 15716, 15560, 15376,
+ 15161, 14913, 14628, 14306, 13944, 13541, 13098, 12616, 12097, 11540, 10952, 10335, 9692, 9030, 8362,
+ 7699, 7045, 6400, 5769, 5155, 4560, 3990, 3448, 2936, 2460, 2022, 1625, 1272, 963, 700,
+ 481, 306, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0};
+#else
+#define PhECU_preTdaFx16ms_WB_Q14 NULL
+#endif
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_sWB_Q14[384] = {
+ -22499, -22471, -22152, -21551, -20715, -19688, -18527, -17277, -15982, -14679, -13393, -12145, -10954, -9826,
+ -8760, -7763, -6831, -5958, -5149, -4394, -3688, -3029, -2410, -1831, -1285, -769, -279, 186,
+ 630, 1055, 1462, 1856, 2236, 2606, 2966, 3317, 3662, 3999, 4330, 4658, 4981, 5301,
+ 5618, 5933, 6246, 6556, 6866, 7175, 7481, 7788, 8093, 8398, 8702, 9004, 9306, 9606,
+ 9906, 10205, 10502, 10798, 11092, 11385, 11676, 11965, 12252, 12537, 12820, 13101, 13379, 13655,
+ 13929, 14200, 14470, 14732, 14977, 15208, 15422, 15622, 15804, 15970, 16121, 16256, 16374, 16478,
+ 16567, 16643, 16703, 16753, 16789, 16815, 16830, 16837, 16835, 16825, 16810, 16789, 16764, 16735,
+ 16704, 16671, 16637, 16604, 16575, 16538, 16503, 16471, 16441, 16414, 16389, 16366, 16345, 16325,
+ 16307, 16291, 16276, 16263, 16250, 16239, 16230, 16221, 16213, 16206, 16200, 16195, 16190, 16187,
+ 16184, 16181, 16180, 16178, 16178, 16178, 16178, 16178, 16180, 16181, 16182, 16185, 16187, 16189,
+ 16191, 16193, 16195, 16198, 16200, 16202, 16205, 16207, 16208, 16211, 16213, 16214, 16215, 16217,
+ 16217, 16218, 16219, 16219, 16220, 16221, 16221, 16221, 16222, 16223, 16224, 16224, 16226, 16227,
+ 16228, 16230, 16233, 16236, 16239, 16242, 16246, 16251, 16256, 16261, 16267, 16274, 16280, 16288,
+ 16295, 16304, 16312, 16321, 16330, 16339, 16349, 16359, 16369, 16379, 16389, 16399, 16409, 16419,
+ 16429, 16439, 16447, 16456, 16465, 16473, 16481, 16489, 16495, 16502, 16508, 16513, 16519, 16523,
+ 16527, 16531, 16534, 16536, 16539, 16541, 16543, 16544, 16545, 16546, 16547, 16547, 16548, 16549,
+ 16549, 16549, 16550, 16551, 16551, 16552, 16554, 16554, 16556, 16558, 16559, 16561, 16563, 16565,
+ 16567, 16570, 16572, 16575, 16578, 16580, 16582, 16584, 16586, 16588, 16590, 16591, 16592, 16593,
+ 16593, 16593, 16593, 16591, 16589, 16587, 16584, 16580, 16575, 16570, 16564, 16557, 16549, 16540,
+ 16530, 16519, 16506, 16493, 16478, 16461, 16443, 16423, 16402, 16379, 16354, 16327, 16297, 16266,
+ 16232, 16195, 16147, 16096, 16039, 15977, 15907, 15828, 15740, 15642, 15531, 15409, 15273, 15122,
+ 14956, 14775, 14577, 14362, 14130, 13879, 13611, 13325, 13021, 12700, 12361, 12006, 11636, 11250,
+ 10851, 10440, 10016, 9583, 9142, 8698, 8255, 7815, 7377, 6944, 6515, 6092, 5675, 5266,
+ 4865, 4475, 4094, 3726, 3370, 3029, 2703, 2393, 2101, 1826, 1571, 1334, 1117, 921,
+ 744, 588, 451, 335, 235, 128, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0};
+#else
+#define PhECU_preTdaFx16ms_sWB_Q14 NULL
+#endif
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_SWB_Q14[512] = {
+ -22482, -22492, -22345, -22020, -21560, -20952, -20236, -19434, -18551, -17624, -16665, -15691, -14716, -13753,
+ -12810, -11889, -11002, -10152, -9335, -8553, -7813, -7108, -6442, -5806, -5206, -4634, -4091, -3574,
+ -3084, -2618, -2173, -1748, -1341, -952, -578, -219, 128, 462, 786, 1099, 1405, 1701,
+ 1989, 2271, 2548, 2818, 3084, 3345, 3601, 3856, 4106, 4354, 4598, 4840, 5082, 5322,
+ 5559, 5795, 6029, 6263, 6496, 6729, 6961, 7192, 7422, 7652, 7882, 8111, 8339, 8567,
+ 8795, 9022, 9249, 9475, 9701, 9926, 10151, 10374, 10597, 10819, 11041, 11261, 11481, 11699,
+ 11917, 12133, 12349, 12563, 12776, 12988, 13198, 13408, 13616, 13823, 14028, 14233, 14437, 14635,
+ 14826, 15007, 15181, 15344, 15499, 15645, 15782, 15910, 16029, 16139, 16239, 16332, 16415, 16490,
+ 16557, 16615, 16667, 16710, 16747, 16777, 16800, 16818, 16829, 16835, 16837, 16834, 16827, 16816,
+ 16803, 16786, 16767, 16746, 16724, 16700, 16675, 16649, 16624, 16601, 16580, 16551, 16524, 16499,
+ 16475, 16453, 16431, 16411, 16392, 16374, 16358, 16342, 16328, 16313, 16301, 16289, 16278, 16268,
+ 16258, 16249, 16241, 16234, 16226, 16220, 16214, 16208, 16204, 16200, 16196, 16192, 16188, 16186,
+ 16184, 16182, 16181, 16179, 16178, 16178, 16177, 16177, 16177, 16178, 16179, 16180, 16181, 16181,
+ 16183, 16185, 16186, 16188, 16189, 16191, 16192, 16195, 16196, 16198, 16200, 16202, 16204, 16205,
+ 16207, 16208, 16210, 16211, 16212, 16213, 16215, 16215, 16216, 16217, 16218, 16219, 16219, 16219,
+ 16220, 16220, 16221, 16221, 16222, 16222, 16222, 16222, 16223, 16223, 16224, 16225, 16226, 16227,
+ 16228, 16230, 16231, 16233, 16235, 16238, 16240, 16243, 16245, 16249, 16253, 16256, 16260, 16264,
+ 16269, 16275, 16279, 16285, 16290, 16296, 16302, 16309, 16315, 16322, 16329, 16336, 16343, 16351,
+ 16358, 16365, 16373, 16381, 16388, 16396, 16403, 16411, 16418, 16425, 16432, 16439, 16446, 16453,
+ 16460, 16466, 16472, 16478, 16484, 16489, 16494, 16499, 16504, 16509, 16513, 16517, 16520, 16524,
+ 16527, 16529, 16532, 16534, 16536, 16538, 16540, 16541, 16543, 16543, 16544, 16545, 16546, 16547,
+ 16547, 16547, 16548, 16548, 16549, 16549, 16550, 16550, 16551, 16551, 16551, 16552, 16553, 16554,
+ 16555, 16555, 16557, 16558, 16559, 16560, 16562, 16563, 16565, 16566, 16569, 16570, 16572, 16573,
+ 16576, 16577, 16579, 16581, 16583, 16585, 16586, 16588, 16589, 16590, 16591, 16592, 16592, 16593,
+ 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16586, 16585, 16581, 16578, 16575, 16571, 16566,
+ 16562, 16556, 16550, 16543, 16536, 16528, 16520, 16511, 16502, 16490, 16479, 16468, 16455, 16441,
+ 16426, 16411, 16394, 16376, 16357, 16337, 16316, 16294, 16270, 16245, 16219, 16191, 16154, 16115,
+ 16075, 16032, 15985, 15934, 15879, 15818, 15751, 15679, 15601, 15517, 15425, 15325, 15218, 15102,
+ 14978, 14845, 14703, 14551, 14390, 14219, 14038, 13847, 13645, 13434, 13213, 12982, 12741, 12490,
+ 12230, 11961, 11683, 11396, 11102, 10800, 10492, 10176, 9855, 9529, 9197, 8864, 8532, 8201,
+ 7872, 7544, 7218, 6894, 6573, 6255, 5940, 5629, 5322, 5020, 4723, 4432, 4147, 3868,
+ 3596, 3332, 3076, 2828, 2590, 2361, 2141, 1931, 1732, 1543, 1366, 1200, 1044, 901,
+ 768, 647, 536, 438, 349, 271, 201, 108, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+#else
+#define PhECU_preTdaFx16ms_SWB_Q14 NULL
+#endif
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 PhECU_preTdaFx16ms_FB_Q14[768] = {
+ -22463, -22493, -22449, -22334, -22148, -21885, -21560, -21179, -20737, -20250, -19726, -19171, -18581, -17972,
+ -17340, -16701, -16050, -15401, -14757, -14114, -13474, -12848, -12237, -11637, -11048, -10478, -9922, -9386,
+ -8864, -8357, -7865, -7393, -6936, -6493, -6069, -5654, -5258, -4874, -4503, -4144, -3801, -3465,
+ -3140, -2829, -2524, -2230, -1944, -1667, -1399, -1136, -884, -636, -395, -158, 72, 296,
+ 514, 728, 938, 1144, 1346, 1545, 1739, 1931, 2119, 2305, 2489, 2670, 2849, 3025,
+ 3199, 3373, 3543, 3713, 3879, 4046, 4211, 4376, 4539, 4700, 4862, 5022, 5182, 5341,
+ 5499, 5657, 5814, 5970, 6126, 6282, 6437, 6592, 6746, 6901, 7056, 7209, 7362, 7517,
+ 7669, 7823, 7976, 8129, 8281, 8433, 8585, 8738, 8890, 9040, 9193, 9343, 9495, 9645,
+ 9796, 9946, 10096, 10245, 10395, 10543, 10693, 10841, 10989, 11137, 11284, 11431, 11578, 11723,
+ 11869, 12014, 12159, 12303, 12446, 12589, 12733, 12874, 13016, 13157, 13298, 13438, 13577, 13716,
+ 13855, 13992, 14129, 14266, 14403, 14537, 14667, 14795, 14918, 15037, 15152, 15263, 15371, 15474,
+ 15573, 15669, 15760, 15847, 15931, 16010, 16084, 16156, 16223, 16287, 16346, 16402, 16453, 16502,
+ 16546, 16587, 16625, 16659, 16690, 16717, 16742, 16763, 16781, 16797, 16810, 16819, 16827, 16833,
+ 16836, 16837, 16836, 16833, 16828, 16822, 16815, 16805, 16794, 16783, 16770, 16756, 16743, 16727,
+ 16712, 16695, 16679, 16663, 16645, 16629, 16612, 16598, 16584, 16565, 16546, 16529, 16511, 16495,
+ 16479, 16463, 16449, 16434, 16420, 16408, 16395, 16383, 16371, 16360, 16350, 16339, 16329, 16321,
+ 16311, 16303, 16295, 16287, 16280, 16272, 16266, 16260, 16253, 16247, 16242, 16237, 16232, 16227,
+ 16223, 16219, 16215, 16211, 16207, 16205, 16202, 16199, 16196, 16194, 16191, 16189, 16187, 16186,
+ 16184, 16183, 16181, 16180, 16180, 16179, 16178, 16178, 16177, 16177, 16177, 16177, 16177, 16177,
+ 16178, 16178, 16179, 16179, 16180, 16181, 16182, 16183, 16184, 16185, 16186, 16187, 16188, 16189,
+ 16190, 16191, 16193, 16194, 16195, 16196, 16197, 16199, 16200, 16201, 16202, 16203, 16205, 16206,
+ 16206, 16207, 16208, 16209, 16210, 16211, 16212, 16212, 16213, 16214, 16215, 16215, 16216, 16216,
+ 16217, 16218, 16218, 16218, 16219, 16219, 16219, 16220, 16220, 16220, 16221, 16221, 16221, 16221,
+ 16221, 16222, 16222, 16222, 16223, 16223, 16223, 16224, 16224, 16225, 16225, 16226, 16227, 16227,
+ 16228, 16229, 16230, 16231, 16233, 16234, 16235, 16237, 16237, 16239, 16241, 16243, 16245, 16247,
+ 16249, 16252, 16254, 16257, 16260, 16263, 16266, 16268, 16271, 16275, 16278, 16282, 16286, 16290,
+ 16294, 16298, 16301, 16305, 16310, 16314, 16319, 16323, 16328, 16332, 16337, 16342, 16347, 16352,
+ 16357, 16361, 16366, 16371, 16377, 16382, 16387, 16391, 16396, 16402, 16407, 16412, 16417, 16421,
+ 16426, 16431, 16436, 16441, 16445, 16450, 16454, 16458, 16463, 16467, 16471, 16475, 16480, 16482,
+ 16486, 16490, 16494, 16497, 16500, 16504, 16507, 16510, 16511, 16514, 16517, 16519, 16522, 16524,
+ 16526, 16528, 16530, 16532, 16533, 16535, 16536, 16538, 16539, 16540, 16541, 16542, 16542, 16543,
+ 16543, 16544, 16545, 16545, 16546, 16546, 16546, 16547, 16547, 16547, 16548, 16548, 16548, 16548,
+ 16549, 16549, 16549, 16549, 16550, 16550, 16550, 16551, 16551, 16551, 16552, 16552, 16553, 16554,
+ 16554, 16555, 16556, 16556, 16557, 16558, 16559, 16560, 16561, 16562, 16563, 16564, 16565, 16566,
+ 16567, 16568, 16570, 16571, 16572, 16572, 16574, 16575, 16576, 16577, 16579, 16580, 16581, 16582,
+ 16583, 16585, 16586, 16587, 16588, 16589, 16589, 16590, 16591, 16592, 16592, 16593, 16593, 16593,
+ 16593, 16593, 16593, 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16588, 16586, 16585, 16583,
+ 16581, 16579, 16576, 16574, 16572, 16569, 16566, 16562, 16559, 16555, 16551, 16546, 16542, 16538,
+ 16533, 16527, 16521, 16515, 16510, 16503, 16496, 16489, 16481, 16474, 16465, 16457, 16448, 16439,
+ 16428, 16419, 16408, 16396, 16385, 16373, 16360, 16347, 16333, 16320, 16305, 16290, 16274, 16258,
+ 16240, 16223, 16205, 16186, 16160, 16134, 16109, 16082, 16054, 16024, 15993, 15961, 15926, 15888,
+ 15849, 15808, 15763, 15717, 15667, 15615, 15560, 15502, 15441, 15376, 15308, 15236, 15161, 15082,
+ 14999, 14913, 14822, 14727, 14628, 14525, 14417, 14306, 14190, 14069, 13944, 13814, 13679, 13541,
+ 13398, 13250, 13098, 12943, 12782, 12616, 12447, 12273, 12096, 11915, 11729, 11541, 11348, 11151,
+ 10952, 10749, 10543, 10335, 10123, 9909, 9692, 9473, 9253, 9032, 8810, 8589, 8369, 8149,
+ 7929, 7711, 7492, 7276, 7059, 6845, 6631, 6418, 6207, 5997, 5789, 5582, 5378, 5175,
+ 4975, 4777, 4583, 4389, 4200, 4012, 3827, 3646, 3468, 3294, 3123, 2956, 2793, 2634,
+ 2479, 2328, 2181, 2039, 1902, 1768, 1639, 1517, 1398, 1284, 1176, 1072, 973, 879,
+ 791, 707, 629, 556, 486, 423, 364, 310, 261, 213, 163, 85, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+#else
+#define PhECU_preTdaFx16ms_FB_Q14 NULL
+#endif
+
+RAM_ALIGN const Word16 *const PhECU_wins[5][3] = {
+ /* 3ms hamm(left part) , 16ms(center IWHR(periodic)*MDCT-anaQ14) , 2ms(initial MDCT-ana in Q14) */
+ /*8 kHz*/ {PhECU_whr16ms_NB_Q15, PhECU_preTdaFx16ms_NB_Q14, PhECU_preTdaFx16ms_128_pre_Q14},
+ /*16 kHz*/ {PhECU_whr16ms_WB_Q15, PhECU_preTdaFx16ms_WB_Q14, PhECU_preTdaFx16ms_256_pre_Q14},
+ /*24 kHz*/ {PhECU_whr16ms_sWB_Q15, PhECU_preTdaFx16ms_sWB_Q14, PhECU_preTdaFx16ms_384_pre_Q14},
+ /*32 kHz*/ {PhECU_whr16ms_SWB_Q15, PhECU_preTdaFx16ms_SWB_Q14, PhECU_preTdaFx16ms_512_pre_Q14},
+ /*48 kHz*/ {PhECU_whr16ms_FB_Q15, PhECU_preTdaFx16ms_FB_Q14, PhECU_preTdaFx16ms_768_pre_Q14}};
+
+/* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */
+/* 1.25 *2*pi table for low complex and low angle resolution rand_phase_fx */
+RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[40] = {
+ 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138, 32767, 32138, 30274, 27246, 23170, 18205,
+ 12540, 6393, 0, -6393, -12540, -18205, -23170, -27246, -30274, -32138, -32768, -32138, -30274, -27246,
+ -23170, -18205, -12540, -6393, 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138};
+
+/* (PHECU_LA_48K == 0) */
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 w_new_fs_8_LA_0[OLA_LEN_8K] = {0, 411, 1623, 3574, 6169, 9275, 12738,
+ 16384, 20030, 23493, 26599, 29194, 31145, 32357};
+
+
+RAM_ALIGN const Word16 w_old_fs_8_LA_0[OLA_LEN_8K] = {
+
+ /* ( 32768-fliplr(w_new_fs_8_LA_0) ) *[whr3ms(0:13)*/
+ 2621, 2721, 3001, 3401, 3836, 4205, 4411, 4377, 4063, 3475, 2673, 1766, 901, 253};
+#else
+#define w_new_fs_8_LA_0 NULL
+#define w_old_fs_8_LA_0 NULL
+#endif /* SUBSET_NB */
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 w_new_fs_16_LA_0[OLA_LEN_16K] = {
+ 0, 103, 411, 919, 1623, 2511, 3574, 4799, 6169, 7667, 9275, 10973, 12738, 14550,
+ 16384, 18218, 20030, 21795, 23493, 25101, 26599, 27969, 29194, 30257, 31145, 31849, 32357, 32665};
+
+RAM_ALIGN const Word16 w_old_fs_16_LA_0[OLA_LEN_16K] = {2621, 2646, 2719, 2835, 2990, 3175, 3379, 3592, 3801, 3994,
+ 4158, 4282, 4355, 4369, 4317, 4196, 4005, 3746, 3425, 3050,
+ 2635, 2192, 1740, 1299, 889, 531, 250, 66};
+#else
+#define w_new_fs_16_LA_0 NULL
+#define w_old_fs_16_LA_0 NULL
+#endif /* SUBSET_WB */
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 w_new_fs_24_LA_0[OLA_LEN_24K] = {
+ 0, 46, 183, 411, 728, 1133, 1623, 2195, 2847, 3574, 4374, 5240, 6169, 7155,
+ 8192, 9275, 10398, 11555, 12738, 13942, 15160, 16384, 17608, 18826, 20030, 21213, 22370, 23493,
+ 24576, 25613, 26599, 27528, 28394, 29194, 29921, 30573, 31145, 31635, 32040, 32357, 32585, 32722};
+
+RAM_ALIGN const Word16 w_old_fs_24_LA_0[OLA_LEN_24K] = {
+ 2621, 2632, 2665, 2718, 2790, 2881, 2987, 3106, 3235, 3372, 3512, 3653, 3790, 3919,
+ 4038, 4143, 4229, 4295, 4337, 4353, 4340, 4298, 4225, 4121, 3986, 3821, 3628, 3408,
+ 3165, 2902, 2622, 2330, 2032, 1732, 1437, 1152, 884, 640, 426, 249, 114, 30};
+#else
+#define w_new_fs_24_LA_0 NULL
+#define w_old_fs_24_LA_0 NULL
+#endif /* SUBSET_SSWB */
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 w_new_fs_32_LA_0[OLA_LEN_32K] = {
+ 0, 26, 103, 231, 411, 640, 919, 1247, 1623, 2044, 2511, 3022, 3574, 4167,
+ 4799, 5467, 6169, 6903, 7667, 8459, 9275, 10114, 10973, 11848, 12738, 13640, 14550, 15465,
+ 16384, 17303, 18218, 19128, 20030, 20920, 21795, 22654, 23493, 24309, 25101, 25865, 26599, 27301,
+ 27969, 28601, 29194, 29746, 30257, 30724, 31145, 31521, 31849, 32128, 32357, 32537, 32665, 32742};
+
+RAM_ALIGN const Word16 w_old_fs_32_LA_0[OLA_LEN_32K] = {
+ 2621, 2628, 2646, 2676, 2717, 2770, 2832, 2904, 2985, 3073, 3167, 3266, 3368, 3473, 3578, 3682, 3784, 3882, 3974,
+ 4059, 4135, 4202, 4257, 4299, 4328, 4342, 4340, 4323, 4288, 4236, 4167, 4081, 3977, 3856, 3719, 3567, 3400, 3220,
+ 3028, 2826, 2615, 2398, 2176, 1952, 1728, 1506, 1290, 1081, 882, 697, 528, 377, 248, 143, 65, 17};
+#else
+#define w_new_fs_32_LA_0 NULL
+#define w_old_fs_32_LA_0 NULL
+#endif /* SUBSET_SWB */
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 w_new_fs_48_LA_0[OLA_LEN_48K] = {
+ 0, 11, 46, 103, 183, 286, 411, 558, 728, 919, 1133, 1367, 1623, 1899,
+ 2195, 2511, 2847, 3201, 3574, 3965, 4374, 4799, 5240, 5697, 6169, 6655, 7155, 7667,
+ 8192, 8728, 9275, 9832, 10398, 10973, 11555, 12144, 12738, 13338, 13942, 14550, 15160, 15771,
+ 16384, 16997, 17608, 18218, 18826, 19430, 20030, 20624, 21213, 21795, 22370, 22936, 23493, 24040,
+ 24576, 25101, 25613, 26113, 26599, 27071, 27528, 27969, 28394, 28803, 29194, 29567, 29921, 30257,
+ 30573, 30869, 31145, 31401, 31635, 31849, 32040, 32210, 32357, 32482, 32585, 32665, 32722, 32757};
+
+RAM_ALIGN const Word16 w_old_fs_48_LA_0[OLA_LEN_48K] = {
+ 2621, 2624, 2632, 2646, 2664, 2688, 2717, 2750, 2789, 2831, 2878, 2929, 2983, 3041, 3101, 3164, 3229,
+ 3296, 3365, 3434, 3504, 3573, 3643, 3711, 3778, 3844, 3907, 3967, 4024, 4078, 4128, 4173, 4213, 4248,
+ 4278, 4301, 4319, 4330, 4334, 4331, 4321, 4303, 4278, 4246, 4206, 4158, 4102, 4038, 3967, 3889, 3803,
+ 3710, 3611, 3505, 3392, 3274, 3150, 3021, 2888, 2750, 2609, 2465, 2319, 2171, 2022, 1873, 1724, 1576,
+ 1430, 1287, 1147, 1011, 880, 755, 637, 527, 424, 331, 248, 175, 114, 65, 29, 7};
+#else
+#define w_new_fs_48_LA_0 NULL
+#define w_old_fs_48_LA_0 NULL
+#endif /* SUBSET_FB */
+
+RAM_ALIGN const Word16 *const w_new[5] = {w_new_fs_8_LA_0, w_new_fs_16_LA_0, w_new_fs_24_LA_0, w_new_fs_32_LA_0,
+ w_new_fs_48_LA_0};
+RAM_ALIGN const Word16 *const w_old[5] = {w_old_fs_8_LA_0, w_old_fs_16_LA_0, w_old_fs_24_LA_0, w_old_fs_32_LA_0,
+ w_old_fs_48_LA_0};
+
+RAM_ALIGN const Word16 COPY_LEN[5] = {COPY_LEN_8K, COPY_LEN_16K, COPY_LEN_24K, COPY_LEN_32K, COPY_LEN_48K}; /* 2ms */
+RAM_ALIGN const Word16 OLA_LEN[5] = {OLA_LEN_8K, OLA_LEN_16K, OLA_LEN_24K, OLA_LEN_32K, OLA_LEN_48K}; /*1.75 ms mix */
+
+RAM_ALIGN const Word16 num_FsByResQ0[5] = {LPROT8K, LPROT16K, LPROT24K, LPROT32K, LPROT48K};
+RAM_ALIGN const Word16 *const LprotSzPtr = num_FsByResQ0;
+RAM_ALIGN const Word16 InvLprot_Q22[5] = {INV_LPROT8K_Q22, INV_LPROT16K_Q22, INV_LPROT24K_Q22, INV_LPROT32K_Q22,
+ INV_LPROT48K_Q22};
+RAM_ALIGN const Word16 PhEcuFftScale[5] = {0, 0, 8, 0, 4};
+
+RAM_ALIGN const Word16 oneOverFrameQ15Tab[5] = {INV_L_FRAME8K_Q15, INV_L_FRAME16K_Q15, INV_L_FRAME24K_Q15,
+ INV_L_FRAME32K_Q15, INV_L_FRAME48K_Q15};
+
+
+RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[5] = {6, 7, 7, 8, 8}; /* TOTAL FFT adjutmenst shift */
+RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[5] = {32767, 32767, 21845, 32767,
+ 21845}; /* fractional fft adjustment 1./ fft_fs_scale */
+
+RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[MAX_LGW] = {3277, 3277, 3277, 3277, 3277,
+ 3277, 3277, 3277, 3277}; /* for now all fixed to 10dB */
+RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[MAX_LGW] = {
+ 3277, 3277, 3277, 3277, 3277,
+ 3277, 3277, 3277, 3277}; /* thresh_rise_dB=10; thresh_lin = 1.0/( 10^(thresh_rise_dB/10) ); */
+
+RAM_ALIGN const Word16 mdct_grp_bins_fx[MAX_LGW + 2] = {4, 14, 24, 44, 84, 164, 244, 324, 404, 484};
+RAM_ALIGN const Word16 xavg_N_grp_fx[5] = {4, 5, 6, 7, 8};
+
+
+RAM_ALIGN const Word16 spec_shape_headroom[5] = {3, 4, 4, 4, 4};
+RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ] = {80, 160, 240, 320, 480, 960}; /* 10ms */
+RAM_ALIGN const Word16 hamm_len2Tab[5] = {24, 48, 72, 96, 144}; /* 3 ms*/
+
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout*/
+#else
+# ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/
+ 16384,11585,8192,5792,4096,2896,2048,1448,1024,724,512,362,256,181,128,91,64,45,32,23,16,11,8,6,4,3,2,1,1,1};
+RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/
+ 16384,13777,11585,9742,8192,6889,5793,4871,4096,3444,2896,2435,2048,1722,1448,1218,1024,861,724,609,512,431,362,304,256,215,181,152,128,108,91,76,64,54,45,38,32,27,23,19,16,13,11,10,8,7,6,5,4,3,3,2,2,2,1,1,1,1,1,1};
+# endif
+#endif
+
+RAM_ALIGN const Word16 NN_thresh = 0x7800; /* 30*2^10 */
+RAM_ALIGN const Word16 NN_thresh_exp = -10;
+/* Tone detector */
+#ifdef CR8_E_TONE_DETECTOR
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 TD_HR_thresh_10ms = 83402;
+# ifdef ENABLE_075_DMS_MODE
+RAM_ALIGN const Word32 TD_HR_thresh_7_5ms = 743496;
+# endif
+RAM_ALIGN const Word32 TD_HR_thresh_5ms = 382564;
+RAM_ALIGN const Word32 TD_HR_thresh_2_5ms = 301695;
+# endif /* ENABLE_HR_MODE */
+#endif /* CR8_E_TONE_DETECTOR */
+RAM_ALIGN const Word32 BW_thresh_quiet[4] = {0x14000000, 0xA000000, 0xA000000, 0xA000000}; /* [20,10,10,10]*2^24 */
+RAM_ALIGN const Word16 BW_thresh_quiet_exp = 31 - 24;
+RAM_ALIGN const Word16 BW_thresh_brickwall[4] = {
+ 1036, 164, 327, 327}; /* (1/(10^(ctrl.BW_thresh_brickwall/10))*2^15) with [15,23,20,20] dB*/
+
+RAM_ALIGN const Word16 BW_brickwall_dist[4] = {4, 4, 3, 1};
+RAM_ALIGN const Word16 BW_warp_idx_start_16k[4] = {
+ 53, 0, 0, 0}; /* indices for warped bands, with an offset of [17,23,23,23] bins for the start_idx */
+RAM_ALIGN const Word16 BW_warp_idx_stop_16k[4] = {
+ 63, 0, 0,
+ 0}; /*'-1' since this is not matlab and another '-1' because of the different formatting of acc_coeff_per_band*/
+RAM_ALIGN const Word16 BW_warp_idx_start_24k[4] = {47, 59, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_24k[4] = {56, 63, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_32k[4] = {44, 54, 60, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_32k[4] = {52, 59, 63, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_48k[4] = {41, 51, 57, 61};
+RAM_ALIGN const Word16 BW_warp_idx_stop_48k[4] = {49, 55, 60, 63};
+RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_start_16k, BW_warp_idx_start_24k, BW_warp_idx_start_32k, BW_warp_idx_start_48k};
+RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_stop_16k, BW_warp_idx_stop_24k, BW_warp_idx_stop_32k, BW_warp_idx_stop_48k};
+
+RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4] = {4, 4, 3, 1};
+RAM_ALIGN const Word16 BW_warp_idx_start_16k_5ms[4] = {39, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_16k_5ms[4] = {49, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_24k_5ms[4] = {35, 47, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_24k_5ms[4] = {44, 51, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_32k_5ms[4] = {34, 44, 50, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_32k_5ms[4] = {42, 49, 53, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_48k_5ms[4] = {32, 42, 48, 52};
+RAM_ALIGN const Word16 BW_warp_idx_stop_48k_5ms[4] = {40, 46, 51, 54};
+RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_start_16k_5ms, BW_warp_idx_start_24k_5ms, BW_warp_idx_start_32k_5ms, BW_warp_idx_start_48k_5ms};
+RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_stop_16k_5ms, BW_warp_idx_stop_24k_5ms, BW_warp_idx_stop_32k_5ms, BW_warp_idx_stop_48k_5ms};
+
+RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4] = {4, 4, 3, 1};
+RAM_ALIGN const Word16 BW_warp_idx_start_16k_2_5ms[4] = {24, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_16k_2_5ms[4] = {34, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_24k_2_5ms[4] = {24, 35, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_24k_2_5ms[4] = {32, 39, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_32k_2_5ms[4] = {24, 33, 39, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_32k_2_5ms[4] = {31, 38, 42, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_48k_2_5ms[4] = {22, 31, 37, 41};
+RAM_ALIGN const Word16 BW_warp_idx_stop_48k_2_5ms[4] = {29, 35, 40, 43};
+RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_start_16k_2_5ms, BW_warp_idx_start_24k_2_5ms, BW_warp_idx_start_32k_2_5ms, BW_warp_idx_start_48k_2_5ms};
+RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = {
+ BW_warp_idx_stop_16k_2_5ms, BW_warp_idx_stop_24k_2_5ms, BW_warp_idx_stop_32k_2_5ms, BW_warp_idx_stop_48k_2_5ms};
+
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4] = {4, 4, 3, 2};
+RAM_ALIGN const Word16 BW_warp_idx_start_16k_7_5ms[4] = {51, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_16k_7_5ms[4] = {63, 0, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_24k_7_5ms[4] = {45, 58, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_24k_7_5ms[4] = {55, 63, 0, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_32k_7_5ms[4] = {42, 53, 60, 0};
+RAM_ALIGN const Word16 BW_warp_idx_stop_32k_7_5ms[4] = {51, 58, 63, 0};
+RAM_ALIGN const Word16 BW_warp_idx_start_48k_7_5ms[4] = {40, 51, 57, 61};
+RAM_ALIGN const Word16 BW_warp_idx_stop_48k_7_5ms[4] = {48, 55, 60, 63};
+RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[] = {
+ BW_warp_idx_start_16k_7_5ms, BW_warp_idx_start_24k_7_5ms, BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms};
+RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[] = {
+ BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms, BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms};
+# endif
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400, 400};
+RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[] = {80, 160, 240, 320, 400, 400};
+RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3, 0};
+#else /* ENABLE_HR_MODE */
+RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400};
+RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3};
+#endif /* ENABLE_HR_MODE */
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 LowDelayShapes_n960_len[6] = {130, 260, 390, 520, 780, 1560};
+#else
+RAM_ALIGN const Word16 LowDelayShapes_n960_len[5] = {130, 260, 390, 520, 780};
+#endif
+RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ] = {30,
+ 60,
+ 90,
+ 120,
+ 180
+#ifdef ENABLE_HR_MODE
+ , 360
+#endif
+};
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_HR_MODE
+const Word16 LowDelayShapes_n960_len_7_5ms[6] = {106, 212, 318, 424, 636, 1272};
+# else
+const Word16 LowDelayShapes_n960_len_7_5ms[5] = {106, 212, 318, 424, 636};
+# endif
+const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ] = {14, 28, 42, 56, 84
+# ifdef ENABLE_HR_MODE
+ , 168
+# endif
+};
+# ifdef ENABLE_HR_MODE
+# ifdef SUBSET_NB
+const Word32 MDCT_WINDOW_FS_8000_frame_ms_75[106] = {
+ 4627440, 11253200, 21594770, 36220454, 55523513, 79715027, 108949241, 143324500, 182870991,
+ 227518888, 277136190, 331449220, 390143896, 452770029, 518831181, 587821768, 659169189, 732247130,
+ 806397033, 880930033, 955136210, 1028289061, 1099721013, 1168761191, 1234831373, 1297335398, 1355817068,
+ 1409866562, 1459158403, 1503372583, 1542341368, 1575958063, 1604141948, 1626962506, 1644516439, 1657006271,
+ 1664740913, 1668084651, 1667510566, 1663566793, 1656808751, 1647805301, 1637186879, 1625507591, 1613355502,
+ 1601336341, 1590266842, 1579708994, 1571001708, 1564080946, 1558867236, 1555257286, 1553127519, 1552339115,
+ 1552734517, 1554146897, 1556401387, 1559318893, 1562715844, 1566405205, -1570197717, -1573904742, -1577333468,
+ -1580290211, -1582582625, -1584022156, -1584425628, -1583621336, -1581452727, -1577790475, -1572531065, -1565603566,
+ -1556974029, -1546637213, -1533223967, -1517247857, -1497930249, -1474813741, -1447477329, -1415559391, -1378853853,
+ -1337198324, -1290524957, -1238912889, -1182546000, -1121735805, -1056935470, -988679598, -917579357, -844370566,
+ -769774729, -694577976, -619621377, -545775321, -473935196, -404978161, -339758802, -279035319, -223452287,
+ -173535871, -129697804, -92268521, -61482210, -37424210, -19913685, -8400842};
+# else
+# define MDCT_WINDOW_FS_8000_frame_ms_75 NULL
+# endif
+# ifdef SUBSET_WB
+const Word32 MDCT_WINDOW_FS_16000_frame_ms_75[212] = {
+ 2448850, 4225281, 6560055, 9518849, 13169928, 17558685, 22724572, 28709046, 35532706,
+ 43206772, 51759643, 61197652, 71531905, 82773688, 94926633, 107995294, 121978042, 136866522,
+ 152653815, 169326944, 186873869, 205260070, 224464206, 244469708, 265226672, 286694090, 308842566,
+ 331620399, 354982140, 378884306, 403282899, 428126460, 453358062, 478925896, 504771155, 530831178,
+ 557056009, 583378298, 609738583, 636071404, 662314239, 688406753, 714278048, 739869110, 765133864,
+ 789997902, 814413107, 838333634, 861699657, 884456686, 906561215, 927970820, 948653245, 968562870,
+ 987675635, 1005965699, 1023398499, 1039938064, 1055570884, 1070287165, 1084066983, 1096897234, 1108786027,
+ 1119713468, 1129673618, 1138691939, 1146759882, 1153881756, 1160087929, 1165385723, 1169796304, 1173355296,
+ 1176085471, 1178017803, 1179194996, 1179657892, 1179448026, 1178622117, 1177223060, 1175290297, 1172896803,
+ 1170081494, 1166887472, 1163391971, 1159633509, 1155652038, 1151518603, 1147273273, 1142969676, 1138666561,
+ 1134412515, 1130255869, 1126558117, 1122496331, 1118765157, 1115363902, 1112285558, 1109526458, 1107080797,
+ 1104939816, 1103098430, 1101543766, 1100269289, 1099261964, 1098510648, 1098002762, 1097726182, 1097665183,
+ 1097807233, 1098135900, 1098637579, 1099295163, 1100094642, 1101018650, 1102052611, 1103178569, 1104381936,
+ 1105644852, 1106951761, 1108284322, -1109627660, -1110963442, -1112276637, -1113548581, -1114763260, -1115902204,
+ -1116950143, -1117888308, -1118701309, -1119370903, -1119882282, -1120217558, -1120362527, -1120300271, -1120018073,
+ -1119500244, -1118735095, -1117710865, -1116417682, -1114844247, -1112986355, -1110833953, -1108385410, -1105635984,
+ -1102584489, -1099232427, -1095578582, -1091628491, -1086655755, -1081531176, -1075887278, -1069676603, -1062851542,
+ -1055375495, -1047209387, -1038304906, -1028645771, -1018191542, -1006905821, -994788854, -981815515, -967960849,
+ -953236015, -937625018, -921120793, -903739802, -885489416, -866385515, -846456825, -825718325, -804213946,
+ -781984241, -759069751, -735509614, -711369811, -686704607, -661557703, -636008311, -610118476, -583941228,
+ -557562076, -531035554, -504439473, -477846967, -451338312, -424989596, -398869327, -373061710, -347653667,
+ -322717851, -298330826, -274560095, -251498346, -229196510, -207718889, -187124805, -167466055, -148790641,
+ -131139192, -114544857, -99042767, -84660988, -71425324, -59356162, -48470733, -38776535, -30272788,
+ -22943830, -16759108, -11669404, -7602417, -4461896 };
+# else
+# define MDCT_WINDOW_FS_16000_frame_ms_75 NULL
+# endif
+# ifdef SUBSET_SSWB
+const Word32 MDCT_WINDOW_FS_24000_frame_ms_75[318] = {
+ 3569045, 5343308, 7469087, 10008734, 12994076, 16456850, 20430606, 24935492, 29988837,
+ 35611849, 41823777, 48643571, 56071893, 64113030, 72783590, 82094564, 92046985, 102645585,
+ 113894977, 125803748, 138373328, 151602749, 165496877, 180058414, 195279760, 211161232, 227698398,
+ 244884561, 262716182, 281188032, 300290267, 320009308, 340323456, 361229416, 382724592, 404784463,
+ 427382077, 450499367, 474123138, 498236134, 522813796, 547827872, 573261791, 599094644, 625301687,
+ 651864990, 678758112, 705953149, 733423301, 761143017, 789088191, 817226769, 845526155, 873965021,
+ 902516713, 931147088, 959825021, 988524208, 1017210384, 1045855673, 1074425690, 1102896296, 1131233244,
+ 1159399102, 1187365932, 1215118091, 1242623432, 1269848445, 1296758792, 1323338775, 1349569176, 1375419011,
+ 1400856664, 1425860452, 1450405500, 1474469418, 1498033883, 1521084216, 1543600669, 1565562699, 1586950362,
+ 1607758181, 1627973678, 1647578495, 1666558705, 1684890994, 1702569411, 1719588669, 1735945131, 1751628259,
+ 1766631537, 1780942408, 1794568179, 1807511369, 1819759624, 1831304037, 1842145330, 1852303571, 1861781063,
+ 1870563512, 1878654482, 1886073254, 1892829269, 1898924017, 1904366694, 1909168622, 1913346034, 1916917451,
+ 1919887595, 1922277229, 1924098512, 1925377637, 1926138245, 1926390110, 1926159966, 1925475348, 1924365664,
+ 1922840889, 1920921471, 1918639476, 1916032510, 1913117957, 1909905898, 1906425851, 1902721668, 1898817211,
+ 1894724624, 1890460570, 1886061947, 1881561147, 1876974490, 1872321669, 1867634952, 1862942467, 1858269659,
+ 1853636539, 1849063935, 1844532585, 1840901848, 1836281978, 1831977326, 1827914309, 1824090826, 1820508133,
+ 1817156298, 1814036518, 1811148878, 1808486122, 1806045111, 1803824889, 1801820200, 1800024837, 1798435525,
+ 1797047955, 1795856425, 1794854508, 1794036436, 1793397182, 1792930395, 1792629275, 1792486811, 1792496288,
+ 1792650932, 1792943382, 1793366271, 1793912436, 1794574259, 1795343928, 1796214319, 1797177519, 1798225910,
+ 1799351580, 1800546365, 1801802795, 1803112835, 1804468826, 1805862173, 1807285016, 1808728934, 1810185719,
+ -1811649011, -1813108149, -1814556719, -1815986412, -1817388652, -1818755380, -1820077746, -1821347804, -1822557195,
+ -1823698097, -1824761958, -1825740466, -1826625594, -1827409009, -1828083190, -1828639928, -1829071236, -1829369628,
+ -1829527454, -1829537126, -1829391729, -1829084485, -1828608410, -1827956837, -1827123677, -1826104316, -1824893520,
+ -1823485537, -1821875510, -1820060164, -1818037432, -1815802468, -1813351581, -1810685587, -1807803281, -1804699559,
+ -1801376829, -1797838749, -1794078176, -1790099212, -1785902823, -1781420977, -1775757613, -1770414541, -1764657397,
+ -1758514553, -1751966917, -1744988832, -1737559493, -1729660865, -1721279216, -1712390301, -1702968220, -1693002531,
+ -1682487980, -1671402851, -1659722977, -1647435681, -1634547191, -1621051754, -1606928538, -1592163286, -1576765074,
+ -1560734340, -1544063625, -1526744164, -1508774562, -1490169863, -1470931267, -1451061598, -1430573380, -1409469788,
+ -1387774154, -1365486503, -1342628496, -1319212449, -1295268938, -1270814307, -1245866917, -1220443956, -1194576202,
+ -1168294208, -1141628864, -1114589888, -1087212858, -1059529377, -1031588154, -1003401722, -974995147, -946412027,
+ -917694623, -888859295, -859943075, -830987474, -802029563, -773092402, -744234412, -715477138, -686865195,
+ -658426713, -630207057, -602244426, -574581369, -547253226, -520293544, -493735699, -467628500, -441995738,
+ -416889401, -392319671, -368337811, -344954670, -322202233, -300117288, -278711744, -258020476, -238052276,
+ -218834457, -200381964, -182706579, -165829103, -149762124, -134517743, -120107705, -106542511, -93830987,
+ -81979923, -70993541, -60872925, -51615362, -43213756, -35655914, -28924065, -22994343, -17836407,
+ -13413907, -9700456, -6939916 };
+# else
+# define MDCT_WINDOW_FS_24000_frame_ms_75 NULL
+# endif
+# ifdef SUBSET_SWB
+const Word32 MDCT_WINDOW_FS_32000_frame_ms_75[424] = {
+ 2898737, 4022405, 5281441, 6723878, 8372060, 10235970, 12328606, 14657777, 17238266,
+ 20075996, 23180406, 26552429, 30204258, 34141418, 38374110, 42901881, 47726394, 52848657,
+ 58275464, 64009892, 70057240, 76417471, 83091786, 90080421, 97386522, 105014921, 112964415,
+ 121235754, 129827911, 138744722, 147986004, 157551876, 167437738, 177647147, 188174741, 199022831,
+ 210184946, 221662871, 233452811, 245554560, 257961285, 270671503, 283672733, 296964439, 310542664,
+ 324409414, 338557330, 352975270, 367652577, 382584217, 397764861, 413190770, 428852496, 444742036,
+ 460850489, 477166934, 493686689, 510401963, 527305552, 544386461, 561639986, 579055156, 596625027,
+ 614334635, 632177187, 650141962, 668224093, 686407908, 704684687, 723041108, 741470500, 759961912,
+ 778506953, 797092489, 815707619, 834339025, 852979862, 871616777, 890238991, 908834402, 927390921,
+ 945902091, 964354406, 982734524, 1001028580, 1019227984, 1037324578, 1055313224, 1073178103, 1090910419,
+ 1108493143, 1125919532, 1143183321, 1160279970, 1177195986, 1193922020, 1210443853, 1226757428, 1242848720,
+ 1258716966, 1274346305, 1289734310, 1304873724, 1319761111, 1334385677, 1348742053, 1362821420, 1376620057,
+ 1390134975, 1403361262, 1416296924, 1428929625, 1441257929, 1453270092, 1464967234, 1476341997, 1487396355,
+ 1498127704, 1508535547, 1518610856, 1528355951, 1537762901, 1546836443, 1555575202, 1563981756, 1572051527,
+ 1579779433, 1587162378, 1594203212, 1600912026, 1607289540, 1613333597, 1619037500, 1624404299, 1629439428,
+ 1634149881, 1638537653, 1642603536, 1646350593, 1649779860, 1652898979, 1655708955, 1658229426, 1660449352,
+ 1662377545, 1664024217, 1665388315, 1666481709, 1667311651, 1667891108, 1668216427, 1668300198, 1668150304,
+ 1667777789, 1667191944, 1666404102, 1665413150, 1664228568, 1662860495, 1661323561, 1659629730, 1657785817,
+ 1655794977, 1653662566, 1651401295, 1649028654, 1646557403, 1643989827, 1641331208, 1638586818, 1635770553,
+ 1632894967, 1629971201, 1627004437, 1624002536, 1620971847, 1617927153, 1614878122, 1611835451, 1608805100,
+ 1605795099, 1602815547, 1599884473, 1596942341, 1594771673, 1591702411, 1588839753, 1586088059, 1583448720,
+ 1580925703, 1578521775, 1576232766, 1574055288, 1571990953, 1570040827, 1568202332, 1566472498, 1564851004,
+ 1563337829, 1561931261, 1560628909, 1559429084, 1558330506, 1557331359, 1556429824, 1555624516, 1554913143,
+ 1554292592, 1553760945, 1553317125, 1552958916, 1552683122, 1552487276, 1552369480, 1552327252, 1552357490,
+ 1552457675, 1552625785, 1552859126, 1553154340, 1553508826, 1553920495, 1554386414, 1554903212, 1555468295,
+ 1556079427, 1556733719, 1557427851, 1558158741, 1558924090, 1559721218, 1560546581, 1561397206, 1562271110,
+ 1563165114, 1564075458, 1564999378, 1565934440, 1566877694, 1567825218, -1568775555, -1569724227, -1570669763,
+ -1571608214, -1572536583, -1573452385, -1574352788, -1575233942, -1576092574, -1576926600, -1577732933, -1578507896,
+ -1579248680, -1579952850, -1580617181, -1581238194, -1581812847, -1582338764, -1582813204, -1583232638, -1583593989,
+ -1583895045, -1584133086, -1584304626, -1584406873, -1584437736, -1584394635, -1584274418, -1584074588, -1583793268,
+ -1583428030, -1582975737, -1582434279, -1581802744, -1581079400, -1580261338, -1579346529, -1578333908, -1577222011,
+ -1576009429, -1574695339, -1573278552, -1571757228, -1570130264, -1568398303, -1566561731, -1564618340, -1562566382,
+ -1560407784, -1558145041, -1555775754, -1553296829, -1550712057, -1548026396, -1545242289, -1542268350, -1538423280,
+ -1535025262, -1531395445, -1527591708, -1523601949, -1519416343, -1515026680, -1510422354, -1505596841, -1500543057,
+ -1495258714, -1489733930, -1483960441, -1477928294, -1471632952, -1465071334, -1458241898, -1451136236, -1443746092,
+ -1436060907, -1428079531, -1419805847, -1411239360, -1402373353, -1393199823, -1383713926, -1373917135, -1363813377,
+ -1353400513, -1342677100, -1331640941, -1320284636, -1308611825, -1296630892, -1284342674, -1271742396, -1258835954,
+ -1245628407, -1232122065, -1218316234, -1204224404, -1189846207, -1175175506, -1160242956, -1145031655, -1129564821,
+ -1113844775, -1097879736, -1081675373, -1065238433, -1048578417, -1031707925, -1014636539, -997375667, -979937295,
+ -962314566, -944532531, -926597437, -908531127, -890341534, -872033654, -853615925, -835103871, -816513734,
+ -797862235, -779149108, -760390220, -741599202, -722791848, -703980340, -685176354, -666389658, -647646244,
+ -628944722, -610316405, -591754523, -573282405, -554915396, -536666275, -518550375, -500581949, -482775076,
+ -465139339, -447692836, -430439482, -413418994, -396596647, -380036004, -363729221, -347677810, -331912032,
+ -316431125, -301242631, -286354637, -271795849, -257560706, -243655300, -230096441, -216894979, -204043835,
+ -191560528, -179450345, -167715723, -156363602, -145400931, -134832648, -124663143, -114896281, -105536276,
+ -96587551, -88053476, -79936384, -72238586, -64962154, -58107752, -51674659, -45661585, -40066372,
+ -34884913, -30111469, -25739290, -21759792, -18161914, -14933570, -12062384, -9522842, -7254663,
+ -5656627 };
+# else
+# define MDCT_WINDOW_FS_32000_frame_ms_75 NULL
+# endif
+# ifdef SUBSET_FB
+const Word32 MDCT_WINDOW_FS_48000_frame_ms_75[636] = {
+ 2204435, 2827689, 3443319, 4131102, 4878935, 5703040, 6599364, 7574899, 8628974,
+ 9768536, 10991420, 12304931, 13709256, 15207323, 16799052, 18489324, 20275023, 22160933,
+ 24148496, 26240076, 28435235, 30739604, 33150351, 35668955, 38294878, 41029635, 43871618,
+ 46825882, 49890883, 53068998, 56360550, 59766888, 63284768, 66918075, 70664961, 74526448,
+ 78503039, 82597929, 86807681, 91135031, 95578822, 100139618, 104816236, 109611835, 114523552,
+ 119554039, 124702224, 129967749, 135348514, 140848111, 146462751, 152193324, 158039847, 164002831,
+ 170078327, 176269443, 182573647, 188991411, 195521914, 202165741, 208918745, 215783357, 222755240,
+ 229832331, 237013913, 244302241, 251692923, 259188940, 266788795, 274490295, 282289304, 290186132,
+ 298175224, 306257381, 314430505, 322694044, 331045821, 339487261, 348012274, 356620678, 365310317,
+ 374079074, 382922254, 391842074, 400834178, 409898068, 419031270, 428232881, 437497913, 446828175,
+ 456219802, 465670981, 475178925, 484743299, 494357854, 504022976, 513735237, 523492799, 533292796,
+ 543136028, 553015990, 562931887, 572880536, 582859524, 592864355, 602896501, 612951047, 623027190,
+ 633121825, 643232873, 653354882, 663488155, 673627234, 683771323, 693918098, 704065470, 714207061,
+ 724344108, 734471992, 744587758, 754688429, 764774608, 774840295, 784884831, 794903648, 804894011,
+ 814851825, 824777247, 834664477, 844515260, 854327259, 864098094, 873822193, 883500485, 893125924,
+ 902697010, 912211002, 921668164, 931065070, 940403253, 949676961, 958885223, 968024298, 977093615,
+ 986086667, 995005058, 1003845874, 1012604766, 1021282611, 1029879030, 1038386135, 1046806723, 1055138039,
+ 1063379017, 1071528406, 1079585832, 1087546197, 1095410412, 1103175087, 1110839263, 1118400067, 1125861251,
+ 1133217689, 1140469587, 1147616705, 1154658548, 1161589135, 1168411456, 1175122212, 1181718798, 1188199640,
+ 1194567214, 1200817042, 1206950737, 1212967954, 1218868269, 1224650873, 1230316551, 1235861165, 1241285527,
+ 1246589565, 1251772729, 1256831629, 1261771016, 1266587826, 1271284733, 1275860443, 1280315823, 1284645497,
+ 1288852346, 1292933744, 1296889962, 1300722079, 1304434734, 1308025653, 1311497310, 1314848195, 1318076916,
+ 1321181451, 1324164254, 1327024207, 1329764950, 1332387885, 1334893025, 1337281173, 1339554157, 1341707740,
+ 1343747791, 1345671522, 1347481634, 1349179572, 1350764422, 1352239980, 1353613012, 1354873992, 1356030340,
+ 1357079368, 1358026526, 1358871638, 1359613742, 1360257791, 1360804083, 1361255397, 1361617096, 1361885808,
+ 1362062609, 1362151603, 1362153995, 1362072233, 1361909271, 1361666938, 1361347766, 1360955593, 1360489817,
+ 1359950116, 1359340101, 1358660855, 1357916180, 1357108339, 1356243400, 1355321087, 1354344570, 1353313776,
+ 1352230258, 1351093731, 1349909242, 1348677915, 1347405592, 1346095404, 1344750475, 1343369336, 1341955495,
+ 1340508098, 1339029437, 1337520955, 1335988076, 1334432030, 1332857982, 1331266254, 1329659151, 1328036799,
+ 1326403000, 1324757066, 1323104230, 1321446604, 1319787700, 1318127699, 1316471738, 1314818892, 1313173031,
+ 1311534229, 1309906742, 1308289975, 1306691587, 1305107061, 1303560954, 1302485706, 1300837265, 1299230148,
+ 1297667349, 1296147118, 1294669845, 1293233008, 1291838729, 1290486465, 1289178223, 1287911298, 1286686132,
+ 1285500617, 1284356733, 1283253302, 1282192039, 1281170798, 1280190420, 1279248602, 1278346792, 1277483349,
+ 1276659918, 1275874601, 1275128550, 1274419448, 1273748350, 1273113203, 1272515449, 1271953180, 1271427649,
+ 1270936717, 1270481540, 1270059928, 1269672963, 1269318382, 1268997326, 1268707731, 1268450837, 1268224483,
+ 1268029756, 1267864381, 1267729424, 1267622629, 1267545013, 1267494302, 1267471571, 1267474578, 1267504402,
+ 1267558747, 1267638603, 1267741668, 1267868942, 1268018115, 1268190239, 1268383008, 1268597404, 1268831071,
+ 1269084943, 1269356717, 1269647473, 1269954877, 1270279875, 1270620090, 1270976496, 1271346828, 1271732058,
+ 1272129716, 1272540744, 1272962829, 1273396990, 1273840888, 1274295422, 1274758248, 1275230417, 1275709517,
+ 1276196415, 1276688706, 1277187379, 1277690114, 1278197794, 1278707969, 1279221647, 1279736503, 1280253498,
+ -1280770244, -1281287656, -1281803343, -1282318265, -1282830085, -1283339807, -1283844964, -1284346432, -1284841866,
+ -1285332250, -1285815146, -1286291410, -1286758593, -1287217737, -1287666452, -1288105628, -1288532876, -1288949203,
+ -1289352245, -1289742931, -1290118731, -1290480607, -1290826232, -1291156571, -1291469183, -1291765004, -1292041634,
+ -1292300151, -1292538184, -1292756663, -1292953166, -1293128674, -1293280819, -1293410658, -1293515818, -1293597309,
+ -1293652773, -1293683213, -1293686282, -1293663081, -1293611326, -1293532118, -1293423149, -1293285472, -1293116803,
+ -1292918254, -1292687534, -1292425784, -1292130842, -1291804017, -1291443255, -1291049775, -1290621337, -1290159111,
+ -1289660945, -1289128099, -1288558489, -1287953483, -1287311252, -1286633366, -1285917866, -1285165943, -1284375393,
+ -1283547520, -1282680564, -1281776335, -1280833350, -1279853230, -1278833852, -1277776244, -1276678466, -1275542433,
+ -1274367185, -1273154903, -1271903726, -1270614321, -1269284275, -1267915816, -1266508671, -1265065178, -1263583140,
+ -1262063220, -1260504007, -1258908698, -1256628331, -1254761985, -1252853377, -1250881358, -1248844632, -1246741358,
+ -1244569594, -1242327619, -1240012651, -1237623600, -1235156149, -1232610864, -1229984110, -1227275248, -1224482272,
+ -1221606271, -1218642652, -1215591412, -1212448650, -1209213243, -1205881571, -1202455146, -1198931234, -1195311772,
+ -1191594196, -1187777826, -1183858288, -1179836046, -1175706321, -1171469469, -1167124636, -1162674694, -1158117379,
+ -1153454731, -1148683225, -1143802349, -1138808714, -1133702904, -1128481825, -1123149280, -1117704914, -1112149514,
+ -1106481061, -1100702139, -1094806903, -1088800296, -1082676113, -1076437274, -1070082677, -1063618676, -1057039488,
+ -1050351248, -1043548836, -1036634133, -1029608325, -1022475106, -1015230021, -1007878923, -1000415821, -992849913,
+ -985179219, -977404151, -969525479, -961538535, -953457394, -945280420, -936999272, -928626277, -920160734,
+ -911603664, -902957625, -894223210, -885402362, -876498250, -867508512, -858440255, -849293347, -840074392,
+ -830781521, -821419104, -811990901, -802499334, -792938179, -783315469, -773636100, -763901035, -754111866,
+ -744278025, -734399140, -724475975, -714510329, -704504133, -694460237, -684383382, -674277250, -664145566,
+ -653994294, -643817229, -633622219, -623410967, -613187040, -602954520, -592717105, -582476532, -572238350,
+ -562002979, -551770150, -541551921, -531349514, -521160592, -510991643, -500852505, -490735715, -480646079,
+ -470590740, -460574626, -450595871, -440662753, -430774557, -420941335, -411160195, -401435877, -391774603,
+ -382174290, -372642476, -363180190, -353786746, -344482765, -335253937, -326094163, -317034690, -308063867,
+ -299187762, -290405275, -281715156, -273134873, -264653333, -256282164, -248014183, -239853113, -231807709,
+ -223884020, -216073113, -208387006, -200816625, -193373144, -186056104, -178871459, -171808633, -164881963,
+ -158086310, -151426496, -144902306, -138514809, -132265008, -126156408, -120188845, -114364736, -108683712,
+ -103148269, -97758088, -92515604, -87420431, -82474860, -77678410, -73033188, -68538592, -64196501,
+ -60006167, -55969182, -52084610, -48353698, -44775286, -41350196, -38077002, -34956005, -31985545,
+ -29165263, -26493253, -23968386, -21588587, -19351751, -17255806, -15297341, -13474667, -11782386,
+ -10220076, -8778515, -7460996, -6246830, -5152154, -4038973 };
+# else
+# define MDCT_WINDOW_FS_48000_frame_ms_75 NULL
+# endif
+
+const Word32 *const LowDelayShapes_n960_7_5ms[5] = {
+ MDCT_WINDOW_FS_8000_frame_ms_75, MDCT_WINDOW_FS_16000_frame_ms_75, MDCT_WINDOW_FS_24000_frame_ms_75, MDCT_WINDOW_FS_32000_frame_ms_75, MDCT_WINDOW_FS_48000_frame_ms_75 };
+# else
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_N60_7_5ms[106] = {
+ 71, 172, 330, 553, 847, 1216, 1662, 2187, 2790, 3472, 4229, 5058, 5953, 6909,
+ 7917, 8969, 10058, 11173, 12305, 13442, 14574, 15690, 16780, 17834, 18842, 19796, 20688, 21513,
+ 22265, 22940, 23534, 24047, 24477, 24825, 25093, 25284, 25402, 25453, 25444, 25384, 25281, 25144,
+ 24981, 24803, 24618, 24434, 24266, 24104, 23972, 23866, 23786, 23731, 23699, 23687, 23693, 23714,
+ 23749, 23793, 23845, 23901, -23959, -24016, -24068, -24113, -24148, -24170, -24176, -24164, -24131, -24075,
+ -23995, -23889, -23758, -23600, -23395, -23151, -22857, -22504, -22087, -21600, -21040, -20404, -19692, -18904,
+ -18044, -17116, -16128, -15086, -14001, -12884, -11746, -10598, -9455, -8328, -7232, -6179, -5184, -4258,
+ -3410, -2648, -1979, -1408, -938, -571, -304, -128};
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_N120_7_5ms[212] = {
+ 37, 64, 100, 145, 201, 268, 347, 438, 542, 659, 790, 934, 1091, 1263,
+ 1448, 1648, 1861, 2088, 2329, 2584, 2851, 3132, 3425, 3730, 4047, 4375, 4713, 5060,
+ 5417, 5781, 6154, 6533, 6918, 7308, 7702, 8100, 8500, 8902, 9304, 9706, 10106, 10504,
+ 10899, 11290, 11675, 12054, 12427, 12792, 13148, 13496, 13833, 14160, 14475, 14779, 15071, 15350,
+ 15616, 15868, 16107, 16331, 16542, 16737, 16919, 17085, 17237, 17375, 17498, 17607, 17702, 17782,
+ 17850, 17904, 17946, 17975, 17993, 18000, 17997, 17984, 17963, 17934, 17897, 17854, 17805, 17752,
+ 17695, 17634, 17571, 17506, 17440, 17375, 17310, 17246, 17190, 17128, 17071, 17019, 16972, 16930,
+ 16893, 16860, 16832, 16808, 16789, 16773, 16762, 16754, 16750, 16749, 16751, 16756, 16764, 16774,
+ 16786, 16800, 16816, 16833, 16852, 16871, 16891, 16911, -16932, -16952, -16972, -16991, -17010, -17027,
+ -17043, -17058, -17070, -17080, -17088, -17093, -17095, -17094, -17090, -17082, -17071, -17055, -17035, -17011,
+ -16983, -16950, -16913, -16871, -16824, -16773, -16717, -16657, -16581, -16503, -16417, -16322, -16218, -16104,
+ -15979, -15843, -15696, -15536, -15364, -15179, -14981, -14770, -14545, -14307, -14055, -13790, -13511, -13220,
+ -12916, -12599, -12271, -11932, -11582, -11223, -10855, -10478, -10095, -9705, -9310, -8910, -8508, -8103,
+ -7697, -7291, -6887, -6485, -6086, -5692, -5305, -4924, -4552, -4189, -3838, -3497, -3170, -2855,
+ -2555, -2270, -2001, -1748, -1511, -1292, -1090, -906, -740, -592, -462, -350, -256, -178,
+ -116, -68};
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_N180_7_5ms[318] = {
+ 54, 82, 114, 153, 198, 251, 312, 380, 458, 543, 638, 742, 856, 978,
+ 1111, 1253, 1405, 1566, 1738, 1920, 2111, 2313, 2525, 2747, 2980, 3222, 3474, 3737,
+ 4009, 4291, 4582, 4883, 5193, 5512, 5840, 6177, 6521, 6874, 7235, 7602, 7978, 8359,
+ 8747, 9141, 9541, 9947, 10357, 10772, 11191, 11614, 12041, 12470, 12902, 13336, 13771, 14208,
+ 14646, 15084, 15521, 15958, 16394, 16829, 17261, 17691, 18118, 18541, 18961, 19376, 19787, 20193,
+ 20593, 20987, 21375, 21757, 22131, 22499, 22858, 23210, 23553, 23889, 24215, 24532, 24841, 25140,
+ 25430, 25709, 25979, 26239, 26488, 26728, 26957, 27175, 27383, 27580, 27767, 27943, 28109, 28264,
+ 28409, 28543, 28666, 28779, 28882, 28975, 29058, 29132, 29195, 29250, 29295, 29332, 29359, 29379,
+ 29391, 29394, 29391, 29380, 29363, 29340, 29311, 29276, 29236, 29192, 29143, 29090, 29033, 28974,
+ 28911, 28846, 28779, 28710, 28640, 28569, 28498, 28426, 28355, 28284, 28214, 28145, 28090, 28019,
+ 27954, 27892, 27833, 27779, 27728, 27680, 27636, 27595, 27558, 27524, 27494, 27466, 27442, 27421,
+ 27403, 27387, 27375, 27365, 27358, 27353, 27351, 27351, 27354, 27358, 27365, 27373, 27383, 27395,
+ 27408, 27423, 27439, 27456, 27474, 27493, 27513, 27534, 27555, 27577, 27599, 27621, -27644, -27666,
+ -27688, -27710, -27731, -27752, -27772, -27792, -27810, -27827, -27844, -27859, -27872, -27884, -27894, -27903,
+ -27909, -27914, -27916, -27917, -27914, -27910, -27902, -27892, -27880, -27864, -27846, -27824, -27800, -27772,
+ -27741, -27707, -27670, -27629, -27585, -27538, -27487, -27433, -27375, -27315, -27251, -27182, -27096, -27014,
+ -26927, -26833, -26733, -26626, -26513, -26393, -26265, -26129, -25985, -25833, -25673, -25504, -25325, -25138,
+ -24941, -24735, -24520, -24294, -24060, -23815, -23561, -23296, -23022, -22738, -22445, -22141, -21829, -21507,
+ -21176, -20836, -20487, -20130, -19764, -19391, -19010, -18622, -18228, -17827, -17420, -17007, -16590, -16167,
+ -15741, -15311, -14877, -14441, -14003, -13563, -13122, -12680, -12238, -11796, -11356, -10917, -10481, -10047,
+ -9616, -9190, -8767, -8350, -7939, -7534, -7135, -6744, -6361, -5986, -5620, -5264, -4916, -4579,
+ -4253, -3937, -3632, -3339, -3058, -2788, -2530, -2285, -2053, -1833, -1626, -1432, -1251, -1083,
+ -929, -788, -659, -544, -441, -351, -272, -205, -148, -106};
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_N240_7_5ms[424] = {
+ 44, 61, 81, 103, 128, 156, 188, 224, 263, 306, 354, 405, 461, 521,
+ 586, 655, 728, 806, 889, 977, 1069, 1166, 1268, 1375, 1486, 1602, 1724, 1850,
+ 1981, 2117, 2258, 2404, 2555, 2711, 2871, 3037, 3207, 3382, 3562, 3747, 3936, 4130,
+ 4329, 4531, 4739, 4950, 5166, 5386, 5610, 5838, 6069, 6305, 6544, 6786, 7032, 7281,
+ 7533, 7788, 8046, 8307, 8570, 8836, 9104, 9374, 9646, 9920, 10196, 10474, 10753, 11033,
+ 11314, 11596, 11879, 12163, 12447, 12731, 13015, 13300, 13584, 13868, 14151, 14433, 14715, 14995,
+ 15274, 15552, 15828, 16103, 16375, 16646, 16914, 17180, 17444, 17704, 17963, 18218, 18470, 18719,
+ 18964, 19206, 19445, 19680, 19911, 20138, 20361, 20580, 20795, 21006, 21212, 21414, 21611, 21804,
+ 21992, 22175, 22354, 22527, 22696, 22860, 23018, 23172, 23321, 23464, 23603, 23736, 23864, 23988,
+ 24106, 24218, 24326, 24428, 24525, 24618, 24705, 24786, 24863, 24935, 25002, 25064, 25121, 25174,
+ 25221, 25264, 25303, 25336, 25366, 25391, 25412, 25428, 25441, 25450, 25455, 25456, 25454, 25448,
+ 25439, 25427, 25412, 25394, 25373, 25350, 25324, 25296, 25265, 25233, 25198, 25162, 25124, 25085,
+ 25045, 25003, 24960, 24916, 24871, 24826, 24780, 24734, 24688, 24641, 24595, 24548, 24502, 24457,
+ 24412, 24367, 24334, 24287, 24244, 24202, 24162, 24123, 24086, 24051, 24018, 23987, 23957, 23929,
+ 23902, 23878, 23855, 23833, 23813, 23795, 23778, 23763, 23749, 23737, 23726, 23717, 23709, 23702,
+ 23696, 23692, 23689, 23687, 23687, 23687, 23689, 23691, 23695, 23699, 23705, 23711, 23718, 23726,
+ 23735, 23744, 23754, 23764, 23776, 23787, 23799, 23812, 23825, 23838, 23852, 23866, 23880, 23894,
+ 23909, 23923, -23938, -23952, -23967, -23981, -23995, -24009, -24023, -24036, -24049, -24062, -24074, -24086,
+ -24097, -24108, -24118, -24128, -24137, -24145, -24152, -24158, -24164, -24168, -24172, -24175, -24176, -24177,
+ -24176, -24174, -24171, -24167, -24161, -24154, -24146, -24136, -24125, -24113, -24099, -24083, -24066, -24048,
+ -24028, -24006, -23983, -23958, -23932, -23904, -23874, -23843, -23810, -23775, -23739, -23701, -23662, -23621,
+ -23579, -23533, -23474, -23423, -23367, -23309, -23248, -23184, -23117, -23047, -22974, -22896, -22816, -22732,
+ -22643, -22551, -22455, -22355, -22251, -22143, -22030, -21913, -21791, -21665, -21534, -21399, -21259, -21114,
+ -20964, -20810, -20651, -20488, -20319, -20146, -19968, -19785, -19598, -19405, -19208, -19007, -18801, -18590,
+ -18375, -18156, -17932, -17704, -17472, -17236, -16996, -16752, -16505, -16254, -16000, -15743, -15482, -15219,
+ -14953, -14684, -14412, -14139, -13863, -13586, -13306, -13025, -12743, -12459, -12174, -11889, -11603, -11316,
+ -11029, -10742, -10455, -10168, -9882, -9597, -9313, -9029, -8748, -8467, -8189, -7912, -7638, -7367,
+ -7097, -6831, -6568, -6308, -6052, -5799, -5550, -5305, -5065, -4828, -4597, -4369, -4147, -3930,
+ -3718, -3511, -3310, -3113, -2923, -2738, -2559, -2386, -2219, -2057, -1902, -1753, -1610, -1474,
+ -1344, -1220, -1102, -991, -887, -788, -697, -611, -532, -459, -393, -332, -277, -228,
+ -184, -145, -111, -86};
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_N360_7_5ms[636] = {
+ 34, 43, 53, 63, 74, 87, 101, 116, 132, 149, 168, 188, 209, 232,
+ 256, 282, 309, 338, 368, 400, 434, 469, 506, 544, 584, 626, 669, 715,
+ 761, 810, 860, 912, 966, 1021, 1078, 1137, 1198, 1260, 1325, 1391, 1458, 1528,
+ 1599, 1673, 1747, 1824, 1903, 1983, 2065, 2149, 2235, 2322, 2411, 2502, 2595, 2690,
+ 2786, 2884, 2983, 3085, 3188, 3293, 3399, 3507, 3617, 3728, 3841, 3955, 4071, 4188,
+ 4307, 4428, 4550, 4673, 4798, 4924, 5051, 5180, 5310, 5442, 5574, 5708, 5843, 5979,
+ 6116, 6255, 6394, 6534, 6676, 6818, 6961, 7106, 7251, 7397, 7543, 7691, 7839, 7988,
+ 8137, 8288, 8438, 8590, 8741, 8894, 9046, 9199, 9353, 9507, 9661, 9815, 9969, 10124,
+ 10279, 10434, 10588, 10743, 10898, 11053, 11207, 11362, 11516, 11670, 11823, 11976, 12129, 12282,
+ 12434, 12585, 12736, 12886, 13036, 13185, 13333, 13481, 13628, 13774, 13919, 14064, 14207, 14349,
+ 14491, 14631, 14771, 14909, 15046, 15183, 15317, 15451, 15584, 15715, 15845, 15973, 16100, 16226,
+ 16350, 16473, 16595, 16715, 16833, 16950, 17065, 17179, 17292, 17402, 17511, 17619, 17724, 17829,
+ 17931, 18032, 18130, 18228, 18323, 18417, 18508, 18598, 18687, 18773, 18858, 18941, 19021, 19101,
+ 19178, 19253, 19327, 19398, 19468, 19536, 19602, 19666, 19729, 19789, 19847, 19904, 19959, 20012,
+ 20063, 20112, 20160, 20205, 20249, 20291, 20331, 20369, 20405, 20440, 20473, 20504, 20533, 20561,
+ 20587, 20611, 20634, 20654, 20674, 20691, 20707, 20722, 20735, 20746, 20756, 20764, 20771, 20777,
+ 20781, 20783, 20785, 20785, 20784, 20781, 20777, 20773, 20767, 20759, 20751, 20742, 20732, 20720,
+ 20708, 20695, 20681, 20666, 20650, 20633, 20616, 20598, 20579, 20560, 20540, 20519, 20498, 20477,
+ 20455, 20432, 20409, 20386, 20362, 20338, 20314, 20289, 20264, 20239, 20214, 20189, 20164, 20138,
+ 20113, 20088, 20063, 20037, 20012, 19988, 19963, 19939, 19914, 19891, 19874, 19849, 19825, 19801,
+ 19778, 19755, 19733, 19712, 19691, 19671, 19652, 19633, 19615, 19598, 19581, 19565, 19549, 19534,
+ 19520, 19506, 19493, 19480, 19468, 19457, 19446, 19436, 19426, 19417, 19408, 19400, 19393, 19386,
+ 19380, 19374, 19368, 19363, 19359, 19355, 19352, 19349, 19346, 19344, 19342, 19341, 19340, 19340,
+ 19340, 19341, 19341, 19343, 19344, 19346, 19348, 19351, 19354, 19357, 19361, 19365, 19369, 19373,
+ 19378, 19383, 19388, 19394, 19399, 19405, 19411, 19417, 19424, 19430, 19437, 19444, 19451, 19458,
+ 19466, 19473, 19481, 19488, 19496, 19504, 19512, 19519, 19527, 19535, -19543, -19551, -19559, -19567,
+ -19574, -19582, -19590, -19598, -19605, -19613, -19620, -19627, -19634, -19641, -19648, -19655, -19661, -19668,
+ -19674, -19680, -19686, -19691, -19696, -19701, -19706, -19711, -19715, -19719, -19723, -19726, -19729, -19732,
+ -19734, -19736, -19737, -19739, -19740, -19740, -19740, -19740, -19739, -19738, -19736, -19734, -19731, -19728,
+ -19725, -19721, -19716, -19711, -19706, -19700, -19693, -19686, -19679, -19671, -19662, -19653, -19643, -19632,
+ -19622, -19610, -19598, -19585, -19572, -19558, -19544, -19529, -19513, -19497, -19481, -19463, -19445, -19427,
+ -19408, -19388, -19368, -19347, -19325, -19303, -19281, -19258, -19234, -19209, -19175, -19146, -19117, -19087,
+ -19056, -19024, -18991, -18956, -18921, -18885, -18847, -18808, -18768, -18727, -18684, -18640, -18595, -18548,
+ -18500, -18451, -18400, -18348, -18294, -18239, -18182, -18124, -18064, -18003, -17940, -17875, -17809, -17741,
+ -17671, -17600, -17528, -17453, -17377, -17299, -17219, -17138, -17055, -16970, -16884, -16795, -16705, -16614,
+ -16520, -16425, -16328, -16230, -16129, -16027, -15923, -15818, -15711, -15602, -15491, -15379, -15265, -15150,
+ -15033, -14914, -14794, -14672, -14549, -14424, -14297, -14170, -14041, -13910, -13778, -13645, -13510, -13374,
+ -13237, -13099, -12959, -12819, -12677, -12534, -12390, -12245, -12099, -11952, -11805, -11656, -11507, -11357,
+ -11206, -11055, -10903, -10750, -10597, -10443, -10289, -10134, -9979, -9824, -9668, -9512, -9356, -9200,
+ -9044, -8888, -8732, -8575, -8419, -8263, -8108, -7952, -7797, -7642, -7488, -7334, -7181, -7028,
+ -6876, -6724, -6573, -6423, -6274, -6125, -5978, -5832, -5686, -5542, -5398, -5256, -5116, -4976,
+ -4838, -4701, -4565, -4431, -4299, -4168, -4038, -3911, -3784, -3660, -3537, -3416, -3297, -3180,
+ -3064, -2951, -2839, -2729, -2622, -2516, -2412, -2311, -2211, -2114, -2018, -1925, -1834, -1745,
+ -1658, -1574, -1492, -1412, -1334, -1258, -1185, -1114, -1046, -980, -916, -854, -795, -738,
+ -683, -631, -581, -533, -488, -445, -404, -366, -329, -295, -263, -233, -206, -180,
+ -156, -134, -114, -95, -79, -62};
+
+const Word16 *const LowDelayShapes_n960_7_5ms[5] = {
+ LowDelayShapes_n960_N60_7_5ms, LowDelayShapes_n960_N120_7_5ms, LowDelayShapes_n960_N180_7_5ms,
+ LowDelayShapes_n960_N240_7_5ms, LowDelayShapes_n960_N360_7_5ms};
+# endif
+#endif
+
+# ifdef ENABLE_HR_MODE
+# ifdef SUBSET_NB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_100[130] = {
+ -961400, -2849747, -6146069, -11183287, -18168658, -27159976, -38041614, -50544991, -64266305,
+ -78702302, -93275005, -107359966, -120331449, -131585369, -140567185, -146788394, -149841031, -149374845,
+ -145077849, -136659567, -123818556, -106218681, -83483575, -55188103, -20866242, 19967468, 67769998,
+ 122921021, 185652202, 255975827, 333632994, 418021593, 508185345, 602779388, 700109939, 798161092,
+ 894722554, 987480940, 1074157272, 1152645644, 1221190247, 1278509567, 1323911980, 1357388583, 1379593462,
+ 1391784272, 1395720478, 1393489246, 1387290092, 1379158144, 1370909958, 1362952657, 1356680081, 1351822616,
+ 1348129706, 1345389974, 1343434137, 1342132875, 1341380238, 1341082389, 1341146030, 1341475565, 1341976666,
+ 1342558820, 1343143270, 1343665484, 1344082633, 1344377759, 1344564351, 1344687981, 1344819951, 1345048163,
+ 1345462207, 1346140636, 1347141158, 1348493131, 1350195802, 1352216474, 1354492706, 1356936321, -1359440659,
+ -1361893201, -1364185723, -1366227332, -1367952395, -1369325253, -1370343007, -1371033982, -1371456025, -1371688758,
+ -1371823378, -1371949513, -1372139932, -1372441219, -1372867302, -1373401073, -1373998949, -1374594994, -1375108467,
+ -1375446347, -1375511619, -1375206190, -1374435007, -1373103717, -1371107592, -1368321163, -1364583182, -1359697421,
+ -1353439826, -1345583929, -1334252006, -1318640435, -1296625734, -1266042179, -1224814360, -1171299094, -1104589425,
+ -1024691930, -932610693, -830326556, -720679178, -607287900, -494260157, -385949065, -286606097, -199964372,
+ -128792415, -74461791, -36690922, -13577456 };
+# else
+# define MDCT_WINDOW_FS_8000_frame_ms_100 NULL
+# endif
+# ifdef SUBSET_WB
+Word32 MDCT_WINDOW_FS_16000_frame_ms_100[260] = {
+ -887375, -1872204, -3197066, -4988439, -7310990, -10227337, -13783209, -18021567, -22958367,
+ -28610377, -34970773, -42018157, -49718535, -58023758, -66873408, -76198163, -85910142, -95927481,
+ -106148057, -116469926, -126789141, -136988509, -146961365, -156599505, -165784108, -174413613, -182384155,
+ -189593925, -195957243, -201380750, -205787662, -209112092, -211278626, -212225338, -211904063, -210251417,
+ -207219014, -202758648, -196811500, -189330359, -180258003, -169532917, -157095614, -142881796, -126812734,
+ -108824087, -88825077, -66738724, -42479347, -15962398, 12903137, 44189991, 77985216, 114347898,
+ 153341694, 195002709, 239360583, 286415769, 336147305, 388513668, 443439084, 500814289, 560507827,
+ 622347139, 686131895, 751624641, 818548945, 886612081, 955480469, 1024792378, 1094174334, 1163233060,
+ 1231563801, 1298756609, 1364398281, 1428080024, 1489417472, 1548030726, 1603570137, 1655722624, 1704220353,
+ 1748832761, 1789380048, 1825732185, 1857837021, 1885694068, 1909350182, 1928926255, 1944599555, 1956591988,
+ 1965173692, 1970654814, 1973392048, 1973753741, 1972126549, 1968905622, 1964477747, 1959200677, 1953414096,
+ 1947497068, 1941982397, 1935699544, 1930081097, 1925079908, 1920651209, 1916744799, 1913315837, 1910318315,
+ 1907712617, 1905458724, 1903525160, 1901880657, 1900501434, 1899362031, 1898444320, 1897728470, 1897199074,
+ 1896837448, 1896629442, 1896556474, 1896603942, 1896753023, 1896988900, 1897292512, 1897649018, 1898040860,
+ 1898455207, 1898875282, 1899290274, 1899686952, 1900057791, 1900392969, 1900688703, 1900940068, 1901148890,
+ 1901315261, 1901446916, 1901549632, 1901635772, 1901716579, 1901808596, 1901925470, 1902085313, 1902301944,
+ 1902593430, 1902971628, 1903450623, 1904038863, 1904746055, 1905575675, 1906532421, 1907613683, 1908818837,
+ 1910139810, 1911570484, 1913097876, 1914709921, 1916389064, 1918119705, 1919880868, -1921655075, -1923419485,
+ -1925156475, -1926844779, -1928468408, -1930009301, -1931454857, -1932791495, -1934012556, -1935109403, -1936080977,
+ -1936924245, -1937643651, -1938242459, -1938730331, -1939115713, -1939412840, -1939633721, -1939796733, -1939915942,
+ -1940009808, -1940092245, -1940180131, -1940284940, -1940419293, -1940589100, -1940802279, -1941058948, -1941361010,
+ -1941703474, -1942082515, -1942488131, -1942912654, -1943342567, -1943766803, -1944168168, -1944533482, -1944844704,
+ -1945086561, -1945239453, -1945288139, -1945213300, -1944999989, -1944629251, -1944086772, -1943353711, -1942414745,
+ -1941250214, -1939842441, -1938166561, -1936199807, -1933912258, -1931274378, -1928248720, -1924799179, -1920884332,
+ -1916465285, -1911499377, -1905951172, -1899784891, -1891449639, -1882086102, -1871092605, -1858022426, -1842504117,
+ -1824150091, -1802570281, -1777395508, -1748280284, -1714926445, -1677106435, -1634654127, -1587483810, -1535592652,
+ -1479074019, -1418108336, -1352953154, -1283959587, -1211573312, -1136287716, -1058670176, -979383239, -899114678,
+ -818587615, -738568308, -659827651, -583145988, -509279027, -438949979, -372825231, -311497711, -255465040,
+ -205107348, -160673323, -122260482, -89825442, -63156242, -41931466, -25668784, -12980788 };
+# else
+# define MDCT_WINDOW_FS_16000_frame_ms_100 NULL
+# endif
+# ifdef SUBSET_SSWB
+Word32 MDCT_WINDOW_FS_24000_frame_ms_100[390] = {
+ -566705, -1110129, -1685050, -2404955, -3290604, -4357398, -5620992, -7096870, -8797110,
+ -10732247, -12913348, -15346312, -18033576, -20979359, -24186040, -27648819, -31361639, -35319387,
+ -39511857, -43926672, -48550894, -53369201, -58364329, -63516998, -68804773, -74208337, -79706124,
+ -85271101, -90877590, -96504202, -102123140, -107704698, -113222623, -118652834, -123968611, -129140789,
+ -134141816, -138946789, -143532274, -147872644, -151941696, -155718471, -159183810, -162313004, -165085094,
+ -167485061, -169496638, -171101141, -172281631, -173021519, -173310456, -173136812, -172483214, -171335676,
+ -169686052, -167521471, -164827705, -161591409, -157800875, -153444385, -148507128, -142973353, -136828628,
+ -130059834, -122650769, -114582255, -105836248, -96398529, -86248633, -75363800, -63725732, -51315501,
+ -38111620, -24094261, -9239538, 6471742, 23056447, 40536457, 58931280, 78254053, 98521159,
+ 119745967, 141936970, 165102364, 189247343, 214372698, 240474371, 267544931, 295575426, 324551903,
+ 354450456, 385246198, 416908490, 449403326, 482689758, 516718794, 551441284, 586801891, 622731215,
+ 659163373, 696029684, 733249762, 770740975, 808417324, 846185475, 883956761, 921637043, 959124688,
+ 996324031, 1033136615, 1069460208, 1105195788, 1140244773, 1174510921, 1207903363, 1240329980, 1271701586,
+ 1301936917, 1330960546, 1358704531, 1385106661, 1410109035, 1433668094, 1455740664, 1476295686, 1495314659,
+ 1512790051, 1528721877, 1543118961, 1555993720, 1567377327, 1577311901, 1585840140, 1593017314, 1598905809,
+ 1603572858, 1607094048, 1609553036, 1611038032, 1611639187, 1611445924, 1610554709, 1609062783, 1607062660,
+ 1604647205, 1601904616, 1598915994, 1595761439, 1592514651, 1589411075, 1586578699, 1582990467, 1579691165,
+ 1576632996, 1573802167, 1571187222, 1568776964, 1566559220, 1564523108, 1562656830, 1560950303, 1559392538,
+ 1557974462, 1556686097, 1555520279, 1554467590, 1553522528, 1552677071, 1551926380, 1551264122, 1550685851,
+ 1550186120, 1549761554, 1549406743, 1549118648, 1548892484, 1548724782, 1548611579, 1548548556, 1548532064,
+ 1548557824, 1548622043, 1548720068, 1548848512, 1549002557, 1549178941, 1549372811, 1549581179, 1549799479,
+ 1550025081, 1550253392, 1550482320, 1550707996, 1550928257, 1551140242, 1551341918, 1551531258, 1551707132,
+ 1551867783, 1552012940, 1552142171, 1552255441, 1552353722, 1552437360, 1552508729, 1552569181, 1552621341,
+ 1552667742, 1552711935, 1552756861, 1552806540, 1552864321, 1552934727, 1553021212, 1553127838, 1553258419,
+ 1553416594, 1553605935, 1553829154, 1554089545, 1554389317, 1554730803, 1555115388, 1555544621, 1556019161,
+ 1556539764, 1557105744, 1557717296, 1558373006, 1559071819, 1559811599, 1560590143, 1561405090, 1562252936,
+ 1563130339, 1564033457, 1564958401, 1565900358, 1566855101, 1567817123, -1568783655, -1569746861, -1570703949,
+ -1571649364, -1572578812, -1573487389, -1574371102, -1575225988, -1576048579, -1576835227, -1577583436, -1578290863,
+ -1578955234, -1579575367, -1580149723, -1580678399, -1581160607, -1581597028, -1581988259, -1582335808, -1582641029,
+ -1582906248, -1583133678, -1583326640, -1583487877, -1583621010, -1583729737, -1583817938, -1583889747, -1583948684,
+ -1583999362, -1584045193, -1584090279, -1584137621, -1584190841, -1584252527, -1584325358, -1584410718, -1584511035,
+ -1584626668, -1584758614, -1584906848, -1585070936, -1585250612, -1585444090, -1585650227, -1585866958, -1586092212,
+ -1586323072, -1586557326, -1586791018, -1587022005, -1587245580, -1587459040, -1587657701, -1587838487, -1587996409,
+ -1588128112, -1588228637, -1588294501, -1588320923, -1588304007, -1588239369, -1588123278, -1587951328, -1587719494,
+ -1587424275, -1587060842, -1586626176, -1586114863, -1585523601, -1584847006, -1584080761, -1583218674, -1582256132,
+ -1581185350, -1580001184, -1578694604, -1577258975, -1575684935, -1573964180, -1572086641, -1570043344, -1567823810,
+ -1565418712, -1562817696, -1560011672, -1556991601, -1553746487, -1550232508, -1545614483, -1540661510, -1535326382,
+ -1529347469, -1522634820, -1515104434, -1506662411, -1497214433, -1486667044, -1474925134, -1461899585, -1447505979,
+ -1431661421, -1414293801, -1395342396, -1374757780, -1352499694, -1328538688, -1302862307, -1275470003, -1246373968,
+ -1215606643, -1183212323, -1149244754, -1113774081, -1076886070, -1038679407, -999271421, -958778521, -917331256,
+ -875071965, -832168635, -788780400, -745078907, -701235665, -657439320, -613872407, -570722470, -528178104,
+ -486428392, -445655594, -406038238, -367747699, -330944214, -295781070, -262392452, -230898968, -201404745,
+ -173990773, -148716671, -125619512, -104711740, -85981071, -69390841, -54880490, -42367028, -31748204,
+ -22909680, -15677896, -8320202 };
+# else
+# define MDCT_WINDOW_FS_24000_frame_ms_100 NULL
+# endif
+# ifdef SUBSET_SWB
+Word32 MDCT_WINDOW_FS_32000_frame_ms_100[520] = {
+ -410329, -796949, -1136328, -1530183, -1997206, -2544529, -3177199, -3900727, -4721409,
+ -5644580, -6674901, -7816606, -9073542, -10449649, -11947654, -13568981, -15314575, -17185616,
+ -19183576, -21308469, -23557934, -25929130, -28420717, -31030313, -33753791, -36586142, -39522623,
+ -42558881, -45688908, -48905915, -52203334, -55573600, -59008578, -62500911, -66043225, -69627153,
+ -73242249, -76878656, -80528547, -84184130, -87834359, -91467738, -95074499, -98645962, -102173556,
+ -105646999, -109055430, -112389025, -115637823, -118792264, -121843979, -124784385, -127604158, -130292837,
+ -132842231, -135246333, -137497670, -139586545, -141504332, -143245396, -144804682, -146175706, -147351477,
+ -148325994, -149093197, -149646348, -149980871, -150094482, -149982174, -149636889, -149052616, -148226262,
+ -147155224, -145834061, -144257234, -142420419, -140318794, -137947501, -135302755, -132379903, -129173499,
+ -125677248, -121885484, -117793976, -113398013, -108690888, -103666131, -98316590, -92636250, -86619948,
+ -80260566, -73550172, -66480755, -59045143, -51237113, -43048956, -34473252, -25502546, -16127957,
+ -6341514, 3862818, 14491541, 25552349, 37053485, 49000846, 61399638, 74255377, 87574137,
+ 101359692, 115615618, 130345077, 145550314, 161232640, 177393068, 194030243, 211141818, 228724496,
+ 246775667, 265291298, 284263733, 303683434, 323542122, 343829307, 364532416, 385638632, 407133703,
+ 428999825, 451218622, 473771892, 496640476, 519799290, 543222449, 566886347, 590766871, 614834881,
+ 639060282, 663412218, 687860455, 712370477, 736908535, 761442526, 785938885, 810359699, 834668800,
+ 858831376, 882812136, 906573323, 930077938, 953289749, 976173461, 998692986, 1020814305, 1042504195,
+ 1063729320, 1084456529, 1104654343, 1124293323, 1143346837, 1161788685, 1179595571, 1196744793, 1213214499,
+ 1228990130, 1244053625, 1258390343, 1271989157, 1284842646, 1296945646, 1308295983, 1318894029, 1328742964,
+ 1337845893, 1346207620, 1353840346, 1360760354, 1366981286, 1372519590, 1377396138, 1381633759, 1385255026,
+ 1388285177, 1390752262, 1392686884, 1394119237, 1395082423, 1395609697, 1395734288, 1395488163, 1394907750,
+ 1394029226, 1392887172, 1391513953, 1389943438, 1388208885, 1386340921, 1384367440, 1382316364, 1380214130,
+ 1378106162, 1376182641, 1374415552, 1372026612, 1369811233, 1367710559, 1365724178, 1363849407, 1362082203,
+ 1360417744, 1358852161, 1357381258, 1356001076, 1354706993, 1353494673, 1352361089, 1351302228, 1350313689,
+ 1349392506, 1348535330, 1347739116, 1347001032, 1346317031, 1345686404, 1345105561, 1344572298, 1344084536,
+ 1343640384, 1343238137, 1342875748, 1342550922, 1342263301, 1342010831, 1341791477, 1341604203, 1341447356,
+ 1341320237, 1341220346, 1341146654, 1341097800, 1341072665, 1341069082, 1341085615, 1341121386, 1341174740,
+ 1341243587, 1341326852, 1341422956, 1341530950, 1341648658, 1341774344, 1341907686, 1342046793, 1342189996,
+ 1342336371, 1342484315, 1342633509, 1342781772, 1342928111, 1343072442, 1343213120, 1343349339, 1343480101,
+ 1343605189, 1343724192, 1343836029, 1343940104, 1344037064, 1344126250, 1344207727, 1344281010, 1344347228,
+ 1344406398, 1344458631, 1344504740, 1344545486, 1344582197, 1344614878, 1344644716, 1344673602, 1344702406,
+ 1344732123, 1344764116, 1344799913, 1344841581, 1344889533, 1344945396, 1345011275, 1345087987, 1345177164,
+ 1345279600, 1345397199, 1345531309, 1345682002, 1345850876, 1346039023, 1346247352, 1346476070, 1346725599,
+ 1346997017, 1347290788, 1347606421, 1347944342, 1348304546, 1348687326, 1349091759, 1349517389, 1349964590,
+ 1350432001, 1350919119, 1351424549, 1351948150, 1352488782, 1353044492, 1353614173, 1354196920, 1354791164,
+ 1355395130, 1356006741, 1356625062, 1357248513, 1357874066, -1358501833, -1359127963, -1359752565, -1360372594,
+ -1360986451, -1361593178, -1362190669, -1362777107, -1363350886, -1363911059, -1364456475, -1364985125, -1365495818,
+ -1365988370, -1366461329, -1366914145, -1367345397, -1367755425, -1368143727, -1368509329, -1368852492, -1369173176,
+ -1369471783, -1369747786, -1370001627, -1370234382, -1370446455, -1370638040, -1370810046, -1370963570, -1371100229,
+ -1371220085, -1371324505, -1371415420, -1371493639, -1371560818, -1371617789, -1371666695, -1371709196, -1371745710,
+ -1371778346, -1371808661, -1371838047, -1371867517, -1371897959, -1371931304, -1371968763, -1372010342, -1372057396,
+ -1372110702, -1372171094, -1372238686, -1372313498, -1372396683, -1372487751, -1372586771, -1372693072, -1372807320,
+ -1372928910, -1373056739, -1373190393, -1373329652, -1373473500, -1373621114, -1373770813, -1373922515, -1374075203,
+ -1374226645, -1374376513, -1374523166, -1374665655, -1374802265, -1374931057, -1375051695, -1375162397, -1375260925,
+ -1375346302, -1375416903, -1375471622, -1375508310, -1375525267, -1375521592, -1375495812, -1375445706, -1375370134,
+ -1375267707, -1375137383, -1374976617, -1374784711, -1374559999, -1374301455, -1374007032, -1373674676, -1373304076,
+ -1372892947, -1372439276, -1371941405, -1371397503, -1370805562, -1370163465, -1369467701, -1368717718, -1367909588,
+ -1367040649, -1366108055, -1365108685, -1364039842, -1362897427, -1361677778, -1360378277, -1358995048, -1357523990,
+ -1355961737, -1354304757, -1352549921, -1350693234, -1348731568, -1346663222, -1344488796, -1342151873, -1339094859,
+ -1335868526, -1332575618, -1329015998, -1325134514, -1320899332, -1316281926, -1311249778, -1305767783, -1299801189,
+ -1293316467, -1286278496, -1278652937, -1270407089, -1261510752, -1251931832, -1241641304, -1230612600, -1218823121,
+ -1206251778, -1192882032, -1178699247, -1163691417, -1147850058, -1131172617, -1113659053, -1095312137, -1076139342,
+ -1056154695, -1035374650, -1013817533, -991505119, -968465043, -944729088, -920331658, -895311402, -869713787,
+ -843580319, -816956722, -789893244, -762442487, -734669461, -706629428, -678385082, -649998064, -621530231,
+ -593051422, -564628794, -536328929, -508220768, -480373259, -452855166, -425735746, -399081503, -372957401,
+ -347428629, -322556345, -298398778, -275013415, -252453167, -230765335, -209993816, -190178661, -171354066,
+ -153547820, -136781064, -121069202, -106422336, -92843298, -80326106, -68858674, -58425411, -49003701,
+ -40559788, -33054527, -26453090, -20722011, -15806421, -11453718, -6043487 };
+# else
+# define MDCT_WINDOW_FS_32000_frame_ms_100 NULL
+# endif
+# ifdef SUBSET_FB
+Word32 MDCT_WINDOW_FS_48000_frame_ms_100[780] = {
+ -260941, -512326, -694531, -879311, -1080918, -1308853, -1562751, -1845827, -2158684,
+ -2503004, -2880077, -3290946, -3737685, -4221002, -4742864, -5303548, -5904756, -6546614,
+ -7230857, -7957740, -8729060, -9544323, -10404756, -11309433, -12259734, -13255019, -14296724,
+ -15384139, -16518209, -17697344, -18921986, -20190385, -21503384, -22859520, -24259194, -25700342,
+ -27183029, -28705009, -30266328, -31864635, -33500032, -35169872, -36873876, -38609380, -40375887,
+ -42170731, -43993030, -45839524, -47709533, -49600244, -51511244, -53439376, -55383757, -57340675,
+ -59308752, -61284610, -63267293, -65253972, -67243943, -69233263, -71220507, -73201745, -75175694,
+ -77138930, -79090353, -81026756, -82947219, -84848184, -86728232, -88583507, -90412766, -92212306,
+ -93980997, -95715499, -97414829, -99075933, -100697747, -102276727, -103811934, -105299541, -106738717,
+ -108126346, -109462104, -110743333, -111969072, -113135967, -114242829, -115286640, -116267230, -117181898,
+ -118030913, -118811562, -119523250, -120163192, -120730923, -121223904, -121641755, -121981772, -122243774,
+ -122425704, -122528356, -122549198, -122488317, -122342868, -122112204, -121794056, -121388712, -120894363,
+ -120311595, -119637953, -118873094, -118014671, -117062760, -116014831, -114871079, -113629173, -112289425,
+ -110849719, -109309933, -107667532, -105922420, -104072007, -102115976, -100051888, -97879875, -95597465,
+ -93204875, -90699195, -88080200, -85345024, -82492843, -79520968, -76429175, -73215366, -69879179,
+ -66417490, -62829616, -59111848, -55264005, -51283182, -47168943, -42918760, -38531620, -34004372,
+ -29336594, -24525462, -19570192, -14467231, -9215895, -3812888, 1741410, 7449630, 13312759,
+ 19333517, 25513103, 31854549, 38357631, 45024786, 51855914, 58853769, 66018789, 73353520,
+ 80857218, 88531868, 96377212, 104395033, 112584867, 120948431, 129484622, 138194897, 147077806,
+ 156134120, 165362222, 174762717, 184333381, 194074737, 203984869, 214063752, 224308471, 234717970,
+ 245288658, 256019674, 266907692, 277950967, 289145264, 300489211, 311977987, 323609345, 335378203,
+ 347280982, 359312288, 371469093, 383745604, 396138434, 408640853, 421247404, 433950689, 446746484,
+ 459627611, 472589454, 485624370, 498725842, 511885724, 525097999, 538353697, 551646906, 564968308,
+ 578310445, 591664155, 605022969, 618377829, 631721846, 645044713, 658338326, 671592921, 684801497,
+ 697954218, 711043692, 724059806, 736994360, 749837478, 762581648, 775216823, 787735715, 800128161,
+ 812386829, 824502387, 836468309, 848275065, 859915578, 871380881, 882663894, 893755956, 904651429,
+ 915341669, 925821650, 936083534, 946122397, 955931903, 965507514, 974842174, 983932079, 992771963,
+ 1001359538, 1009689065, 1017758097, 1025562027, 1033099052, 1040366302, 1047363095, 1054086968, 1060539102,
+ 1066717272, 1072622704, 1078255082, 1083616279, 1088705978, 1093526428, 1098077639, 1102363841, 1106387711,
+ 1110154526, 1113666093, 1116927603, 1119941829, 1122715077, 1125251563, 1127558143, 1129638911, 1131501374,
+ 1133150240, 1134593560, 1135837167, 1136890075, 1137758087, 1138450616, 1138974310, 1139338430, 1139549551,
+ 1139617253, 1139547254, 1139350624, 1139033981, 1138607794, 1138078811, 1137457063, 1136748191, 1135963275,
+ 1135107610, 1134191756, 1133220410, 1132203794, 1131145038, 1130056206, 1128938553, 1127804154, 1126651875,
+ 1125505224, 1124387956, 1123424960, 1122502936, 1121204059, 1119950632, 1118742198, 1117576653, 1116454214,
+ 1115372925, 1114332841, 1113331819, 1112370092, 1111445403, 1110557933, 1109705650, 1108888492, 1108104203,
+ 1107353139, 1106633126, 1105944161, 1105284140, 1104653414, 1104049906, 1103473745, 1102922793, 1102397465,
+ 1101895930, 1101418393, 1100962642, 1100529407, 1100117107, 1099725702, 1099353203, 1099000764, 1098666499,
+ 1098350488, 1098051309, 1097769862, 1097504226, 1097255015, 1097020632, 1096801846, 1096597180, 1096407228,
+ 1096230254, 1096067339, 1095917048, 1095779800, 1095654043, 1095540974, 1095438919, 1095348396, 1095268166,
+ 1095199173, 1095139611, 1095090409, 1095050175, 1095019519, 1094996963, 1094983471, 1094977391, 1094979525,
+ 1094988385, 1095004796, 1095027271, 1095056499, 1095090869, 1095131425, 1095176627, 1095227052, 1095281232,
+ 1095340201, 1095402343, 1095468278, 1095536534, 1095608171, 1095681620, 1095757514, 1095834402, 1095913392,
+ 1095992947, 1096073625, 1096154019, 1096235421, 1096316155, 1096396797, 1096476293, 1096555751, 1096633346,
+ 1096710075, 1096784773, 1096858327, 1096929351, 1096998877, 1097065514, 1097130458, 1097192392, 1097252182,
+ 1097308660, 1097363134, 1097414177, 1097462864, 1097508260, 1097551529, 1097591240, 1097628824, 1097663320,
+ 1097695680, 1097724878, 1097752577, 1097777519, 1097800889, 1097821938, 1097842083, 1097860192, 1097877707,
+ 1097893767, 1097909925, 1097925238, 1097941056, 1097956579, 1097973457, 1097990704, 1098009705, 1098029761,
+ 1098052600, 1098077182, 1098104865, 1098135087, 1098169468, 1098206820, 1098248699, 1098294539, 1098345796,
+ 1098401373, 1098462829, 1098529452, 1098602617, 1098681182, 1098766743, 1098858507, 1098957729, 1099063375,
+ 1099176931, 1099297350, 1099425943, 1099561602, 1099705648, 1099857107, 1100017184, 1100184629, 1100360829,
+ 1100544624, 1100737006, 1100936785, 1101145313, 1101361273, 1101585583, 1101817094, 1102057069, 1102303875,
+ 1102558446, 1102819734, 1103088684, 1103363640, 1103645734, 1103933619, 1104228082, 1104527573, 1104833025,
+ 1105142974, 1105458288, 1105777328, 1106100968, 1106427742, 1106758401, 1107091175, 1107426928, 1107764262,
+ 1108103811, 1108443736, 1108785137, -1109126464, -1109468075, -1109808418, -1110148595, -1110486758, -1110823540,
+ -1111157536, -1111489609, -1111817975, -1112143382, -1112464352, -1112781755, -1113093934, -1113401755, -1113703734,
+ -1114000803, -1114291390, -1114576277, -1114854097, -1115125982, -1115390248, -1115647841, -1115897690, -1116140732,
+ -1116375302, -1116602670, -1116821661, -1117033199, -1117235935, -1117431235, -1117617882, -1117796873, -1117967024,
+ -1118129738, -1118283734, -1118430232, -1118568236, -1118699084, -1118821642, -1118937239, -1119044805, -1119145850,
+ -1119239316, -1119326479, -1119406526, -1119481081, -1119548979, -1119611618, -1119668271, -1119720525, -1119767262,
+ -1119809963, -1119848051, -1119883112, -1119913933, -1119942166, -1119967238, -1119990533, -1120010991, -1120030373,
+ -1120047967, -1120065185, -1120081021, -1120097158, -1120112780, -1120129265, -1120145650, -1120163521, -1120181998,
+ -1120202553, -1120224032, -1120247880, -1120273333, -1120301601, -1120331401, -1120364428, -1120399639, -1120438004,
+ -1120478543, -1120522718, -1120569068, -1120618782, -1120670906, -1120726540, -1120784227, -1120845302, -1120908575,
+ -1120974930, -1121043024, -1121114079, -1121186673, -1121261863, -1121338234, -1121416691, -1121496045, -1121577316,
+ -1121658638, -1121741144, -1121823756, -1121907065, -1121989354, -1122071945, -1122153400, -1122234287, -1122313032,
+ -1122390771, -1122466015, -1122539413, -1122609356, -1122676929, -1122740622, -1122801070, -1122856613, -1122908312,
+ -1122954661, -1122996249, -1123031496, -1123061471, -1123084522, -1123101354, -1123110442, -1123112631, -1123106394,
+ -1123092556, -1123069422, -1123037982, -1122996721, -1122946267, -1122885196, -1122814464, -1122732221, -1122639444,
+ -1122534864, -1122419021, -1122290207, -1122149656, -1121995788, -1121829044, -1121647967, -1121453676, -1121244410,
+ -1121020792, -1120781333, -1120526836, -1120255693, -1119968555, -1119663488, -1119341437, -1119000986, -1118642248,
+ -1118263342, -1117865480, -1117446686, -1117006965, -1116544763, -1116060878, -1115553126, -1115021782, -1114465065,
+ -1113883468, -1113274918, -1112639632, -1111975615, -1111283324, -1110560756, -1109808026, -1109023086, -1108206431,
+ -1107355953, -1106471748, -1105551963, -1104596956, -1103604680, -1102575570, -1101507722, -1100401422, -1099254985,
+ -1098068882, -1096841318, -1095572135, -1093824443, -1092028958, -1090297711, -1088504795, -1086622918, -1084627237,
+ -1082515433, -1080275819, -1077903929, -1075390736, -1072729748, -1069911131, -1066927638, -1063770248, -1060430896,
+ -1056901504, -1053173546, -1049238310, -1045087876, -1040714437, -1036109920, -1031267875, -1026179775, -1020838674,
+ -1015237521, -1009370093, -1003230227, -996813209, -990113245, -983126698, -975849235, -968277852, -960408557,
+ -952239544, -943768000, -934993585, -925915442, -916534205, -906849190, -896862428, -886574831, -875990255,
+ -865111684, -853943783, -842489873, -830755484, -818745230, -806465779, -793923840, -781127868, -768084617,
+ -754803973, -741294413, -727567055, -713632929, -699502178, -685184041, -670691428, -656036019, -641230326,
+ -626286760, -611223511, -596053211, -580789367, -565447177, -550042966, -534590207, -519104101, -503600887,
+ -488098220, -472611780, -457157918, -441752495, -426412611, -411154642, -395995557, -380951672, -366040108,
+ -351277307, -336679493, -322262126, -308041137, -294032383, -280251079, -266711613, -253427888, -240414233,
+ -227684137, -215250748, -203125310, -191319486, -179843288, -168707738, -157921160, -147492810, -137428529,
+ -127735992, -118418783, -109483185, -100930269, -92764786, -84984919, -77594007, -70587122, -63966522,
+ -57723857, -51860743, -46364893, -41238076, -36463273, -32043815, -27956560, -24209143, -20769591,
+ -17655994, -14819879, -12293428, -9917917, -7494462, -3886267 };
+# else
+# define MDCT_WINDOW_FS_48000_frame_ms_100 NULL
+# endif
+
+# ifdef PACK_MDCT_WINDOWS
+RAM_ALIGN const Word16 * LowDelayShapes_n960[6];
+# else
+RAM_ALIGN const Word32 *const LowDelayShapes_n960[6] = { MDCT_WINDOW_FS_8000_frame_ms_100, MDCT_WINDOW_FS_16000_frame_ms_100,
+ MDCT_WINDOW_FS_24000_frame_ms_100, MDCT_WINDOW_FS_32000_frame_ms_100,
+ MDCT_WINDOW_FS_48000_frame_ms_100, NULL };
+# endif
+
+#else
+RAM_ALIGN const Word16 *const LowDelayShapes_n960[6] = {LowDelayShapes_n960_N80, LowDelayShapes_n960_N160,
+ LowDelayShapes_n960_N240, LowDelayShapes_n960_N320,
+ LowDelayShapes_n960_N480, NULL};
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6] = {70, 140, 210, 280, 420, 840};
+# else
+RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5] = {70, 140, 210, 280, 420};
+# endif
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ] = {10,
+ 20,
+ 30,
+ 40,
+ 60
+# ifdef ENABLE_HR_MODE
+ , 120
+# endif
+};
+
+# ifdef ENABLE_HR_MODE
+# ifdef SUBSET_NB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_25[40] = {
+ 9151354, 37109627, 83712740, 151998210, 242715442, 354150912, 482126354, 620379048,
+ 761296862, 896901837, 1019922302, 1124767307, 1208223590, 1269735636, 1311202326, 1336324669,
+ 1349655864, 1355605615, 1357680847, 1358157082, -1358157082, -1357680847, -1355605615, -1349655864,
+ -1336324669, -1311202326, -1269735636, -1208223590, -1124767307, -1019922302, -896901837, -761296862,
+ -620379048, -482126354, -354150912, -242715442, -151998210, -83712740, -37109627, -9151354};
+# else
+# define MDCT_WINDOW_FS_8000_frame_ms_25 NULL
+# endif
+# ifdef SUBSET_WB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_25[80] = {
+ 9151337, 23138265, 42763907, 68767772, 101782534, 142300433, 190643613, 246939893, 311105303,
+ 382834448, 461599452, 546657840, 637069348, 731721202, 829361019, 928636120, 1028137675, 1126447891,
+ 1222188210, 1314066414, 1400920509, 1481757333, 1555784035, 1622430811, 1681363664, 1732486397, 1775931558,
+ 1812040689, 1841334847, 1864477074, 1882229157, 1895405578, 1904827946, 1911283293, 1915489337, 1918069115,
+ 1919536352, 1920291661, 1920628396, 1920745966, -1920745966, -1920628396, -1920291661, -1919536352, -1918069115,
+ -1915489337, -1911283293, -1904827946, -1895405578, -1882229157, -1864477074, -1841334847, -1812040689, -1775931558,
+ -1732486397, -1681363664, -1622430811, -1555784035, -1481757333, -1400920509, -1314066414, -1222188210, -1126447891,
+ -1028137675, -928636120, -829361019, -731721202, -637069348, -546657840, -461599452, -382834448, -311105303,
+ -246939893, -190643613, -142300433, -101782534, -68767772, -42763907, -23138265, -9151337 };
+# else
+# define MDCT_WINDOW_FS_16000_frame_ms_25 NULL
+# endif
+# ifdef SUBSET_SSWB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_25[120] = {
+ 6100899, 12864132, 21489409, 32196712, 45171875, 60580072, 78565098, 99246695, 122717635,
+ 149041013, 178247915, 210335558, 245265970, 282965259, 323323502, 366195270, 411400805, 458727828,
+ 507933969, 558749783, 610882290, 664019005, 717832373, 771984525, 826132286, 879932323, 933046345,
+ 985146249, 1035919114, 1085071930, 1132335985, 1177470792, 1220267489, 1260551623, 1298185265, 1333068386,
+ 1365139469, 1394375330, 1420790145, 1444433697, 1465388876, 1483768499, 1499711524, 1513378754, 1524948163,
+ 1534609980, 1542561681, 1549003060, 1554131535, 1558137849, 1561202310, 1563491688, 1565156852, 1566331192,
+ 1567129839, 1567649635, 1567969785, 1568153080, 1568247554, 1568288448, -1568288448, -1568247554, -1568153080,
+ -1567969785, -1567649635, -1567129839, -1566331192, -1565156852, -1563491688, -1561202310, -1558137849, -1554131535,
+ -1549003060, -1542561681, -1534609980, -1524948163, -1513378754, -1499711524, -1483768499, -1465388876, -1444433697,
+ -1420790145, -1394375330, -1365139469, -1333068386, -1298185265, -1260551623, -1220267489, -1177470792, -1132335985,
+ -1085071930, -1035919114, -985146249, -933046345, -879932323, -826132286, -771984525, -717832373, -664019005,
+ -610882290, -558749783, -507933969, -458727828, -411400805, -366195270, -323323502, -282965259, -245265970,
+ -210335558, -178247915, -149041013, -122717635, -99246695, -78565098, -60580072, -45171875, -32196712,
+ -21489409, -12864132, -6100899 };
+# else
+# define MDCT_WINDOW_FS_24000_frame_ms_25 NULL
+# endif
+# ifdef SUBSET_SWB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_25[160] = {
+ 4575679, 8767860, 13776210, 19722611, 26689435, 34747238, 43959497, 54383445, 66069923,
+ 79062931, 93399091, 109107106, 126207257, 144710958, 164620379, 185928150, 208617151, 232660396,
+ 258021008, 284652300, 312497943, 341492250, 371560541, 402619617, 434578316, 467338167, 500794115,
+ 534835326, 569346062, 604206611, 639294264, 674484335, 709651210, 744669409, 779414654, 813764938,
+ 847601565, 880810169, 913281687, 944913281, 975609194, 1005281536, 1033850982, 1061247376, 1087410241,
+ 1112289173, 1135844126, 1158045581, 1178874586, 1198322683, 1216391705, 1233093455, 1248449271, 1262489470,
+ 1275252698, 1286785178, 1297139874, 1306375586, 1314555990, 1321748631, 1328023899, 1333453999, 1338111934,
+ 1342070524, 1345401476, 1348174521, 1350456644, 1352311405, 1353798377, 1354972700, 1355884752, 1356579954,
+ 1357098688, 1357476324, 1357743362, 1357925654, 1358044707, 1358118045, 1358159612, 1358180205, -1358180205,
+ -1358159612, -1358118045, -1358044707, -1357925654, -1357743362, -1357476324, -1357098688, -1356579954, -1355884752,
+ -1354972700, -1353798377, -1352311405, -1350456644, -1348174521, -1345401476, -1342070524, -1338111934, -1333453999,
+ -1328023899, -1321748631, -1314555990, -1306375586, -1297139874, -1286785178, -1275252698, -1262489470, -1248449271,
+ -1233093455, -1216391705, -1198322683, -1178874586, -1158045581, -1135844126, -1112289173, -1087410241, -1061247376,
+ -1033850982, -1005281536, -975609194, -944913281, -913281687, -880810169, -847601565, -813764938, -779414654,
+ -744669409, -709651210, -674484335, -639294264, -604206611, -569346062, -534835326, -500794115, -467338167,
+ -434578316, -402619617, -371560541, -341492250, -312497943, -284652300, -258021008, -232660396, -208617151,
+ -185928150, -164620379, -144710958, -126207257, -109107106, -93399091, -79062931, -66069923, -54383445,
+ -43959497, -34747238, -26689435, -19722611, -13776210, -8767860, -4575679 };
+# else
+# define MDCT_WINDOW_FS_32000_frame_ms_25 NULL
+# endif
+# ifdef SUBSET_FB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_25[240] = {
+ 3050456, 5295536, 7753004, 10501942, 13578229, 17006497, 20806969, 24997575, 29594719,
+ 34613583, 40068237, 45971662, 52335732, 59171174, 66487516, 74293042, 82594732, 91398213,
+ 100707709, 110526001, 120854381, 131692624, 143038956, 154890033, 167240926, 180085109, 193414462,
+ 207219271, 221488240, 236208515, 251365705, 266943917, 282925795, 299292569, 316024108, 333098980,
+ 350494519, 368186897, 386151203, 404361529, 422791056, 441412148, 460196455, 479115006, 498138325,
+ 517236531, 536379451, 555536738, 574677975, 593772799, 612791011, 631702693, 650478321, 669088878,
+ 687505964, 705701904, 723649854, 741323899, 758699157, 775751861, 792459455, 808800673, 824755609,
+ 840305794, 855434253, 870125559, 884365881, 898143024, 911446458, 924267340, 936598527, 948434586,
+ 959771781, 970608068, 980943072, 990778052, 1000115868, 1008960932, 1017319150, 1025197865, 1032605778,
+ 1039552878, 1046050356, 1052110513, 1057746665, 1062973048, 1067804709, 1072257401, 1076347473, 1080091765,
+ 1083507488, 1086612119, 1089423293, 1091958692, 1094235940, 1096272508, 1098085614, 1099692137, 1101108528,
+ 1102350741, 1103434158, 1104373531, 1105182928, 1105875693, 1106464406, 1106960861, 1107376047, 1107720140,
+ 1108002502, 1108231688, 1108415463, 1108560820, 1108674010, 1108760573, 1108825377, 1108872657, 1108906059,
+ 1108928685, 1108943144, 1108951592, -1108951592, -1108943144, -1108928685, -1108906059, -1108872657, -1108825377,
+ -1108760573, -1108674010, -1108560820, -1108415463, -1108231688, -1108002502, -1107720140, -1107376047, -1106960861,
+ -1106464406, -1105875693, -1105182928, -1104373531, -1103434158, -1102350741, -1101108528, -1099692137, -1098085614,
+ -1096272508, -1094235940, -1091958692, -1089423293, -1086612119, -1083507488, -1080091765, -1076347473, -1072257401,
+ -1067804709, -1062973048, -1057746665, -1052110513, -1046050356, -1039552878, -1032605778, -1025197865, -1017319150,
+ -1008960932, -1000115868, -990778052, -980943072, -970608068, -959771781, -948434586, -936598527, -924267340,
+ -911446458, -898143024, -884365881, -870125559, -855434253, -840305794, -824755609, -808800673, -792459455,
+ -775751861, -758699157, -741323899, -723649854, -705701904, -687505964, -669088878, -650478321, -631702693,
+ -612791011, -593772799, -574677975, -555536738, -536379451, -517236531, -498138325, -479115006, -460196455,
+ -441412148, -422791056, -404361529, -386151203, -368186897, -350494519, -333098980, -316024108, -299292569,
+ -282925795, -266943917, -251365705, -236208515, -221488240, -207219271, -193414462, -180085109, -167240926,
+ -154890033, -143038956, -131692624, -120854381, -110526001, -100707709, -91398213, -82594732, -74293042,
+ -66487516, -59171174, -52335732, -45971662, -40068237, -34613583, -29594719, -24997575, -20806969,
+ -17006497, -13578229, -10501942, -7753004, -5295536, -3050456 };
+# else
+# define MDCT_WINDOW_FS_48000_frame_ms_25 NULL
+# endif
+#endif
+
+# ifdef ENABLE_HR_MODE
+# ifdef SUBSET_NB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_50[70] = {
+ 1912909, 7335521, 18325724, 36910622, 64974178, 104198418, 155981280, 221305462, 300589079,
+ 393635120, 499623692, 617106989, 744004208, 877694270, 1015162828, 1153137249, 1288239038, 1417150998,
+ 1536791945, 1644447880, 1737962977, 1815833349, 1877263804, 1922306058, 1951829636, 1967471711, 1971505676,
+ 1966594148, 1955602246, 1941502114, 1927310881, 1914588900, 1905592841, 1900063224, 1897652925, 1897963170,
+ 1900562354, 1904988644, 1910750498, 1917333371, -1924208315, -1930837552, -1936677590, -1941187989, -1943846368,
+ -1944164165, -1941697923, -1936063536, -1926966575, -1914246866, -1895468226, -1869147188, -1832534703, -1783214725,
+ -1719263259, -1639330989, -1542778136, -1429960741, -1302431717, -1162827131, -1014564422, -861762630, -709123640,
+ -561741289, -424627691, -302165309, -197940066, -114914393, -55161222, -18600494 };
+# else
+# define MDCT_WINDOW_FS_8000_frame_ms_50 NULL
+# endif
+# ifdef SUBSET_WB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_50[140] = {
+ 834388, 2023133, 3917156, 6701705, 10565521, 15685856, 22235650, 30384241, 40286022,
+ 52095516, 65948322, 81967398, 100265346, 120927126, 144016301, 169574495, 197607091, 228098907,
+ 261006859, 296253144, 333742048, 373344049, 414902600, 458235462, 503129294, 549353006, 596652543,
+ 644762423, 693401311, 742277119, 791098023, 839557429, 887360048, 934211532, 979820668, 1023922652,
+ 1066251747, 1106569674, 1144656239, 1180316465, 1213396318, 1243758349, 1271300584, 1295946391, 1317664404,
+ 1336461856, 1352374790, 1365487180, 1375907723, 1383780765, 1389286272, 1392625157, 1394020824, 1393712039,
+ 1391944281, 1388970703, 1385052050, 1380450904, 1375432870, 1370255673, 1365493257, 1360311818, 1355815371,
+ 1351987330, 1348809662, 1346259072, 1344307938, 1342925268, 1342077528, 1341729312, 1341843769, 1342382749,
+ 1343306801, 1344575110, 1346145481, 1347974400, 1350017219, 1352228384, 1354561632, 1356970112, -1359406807,
+ -1361823903, -1364173707, -1366408059, -1368478813, -1370338075, -1371938535, -1373233878, -1374179166, -1374731135,
+ -1374848407, -1374491689, -1373624022, -1372211199, -1370222452, -1367631371, -1364416934, -1360564607, -1356067324,
+ -1350921653, -1344029735, -1336226439, -1326949476, -1315967441, -1303050661, -1287981322, -1270565808, -1250633190,
+ -1228037147, -1202659404, -1174406746, -1143219019, -1109079369, -1072015866, -1032110341, -989504343, -944386484,
+ -896992664, -847599093, -796504062, -744037160, -690570612, -636495945, -582226621, -528203723, -474881089,
+ -422717084, -372160937, -323635430, -277529378, -234193138, -193941056, -157058932, -123809989, -94431397,
+ -69117849, -47990622, -31057417, -18172622, -9019056 };
+# else
+# define MDCT_WINDOW_FS_16000_frame_ms_50 NULL
+# endif
+# ifdef SUBSET_SSWB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_50[210] = {
+ 564151, 1104419, 1865494, 2894039, 4235165, 5932159, 8033172, 10580362, 13613959,
+ 17177173, 21310358, 26053470, 31441110, 37512859, 44302113, 51841191, 60158985, 69285016,
+ 79244161, 90055834, 101740044, 114307277, 127770768, 142131061, 157390145, 173545185, 190584386,
+ 208498576, 227265343, 246867205, 267275117, 288457873, 310382420, 333006130, 356286886, 380173162,
+ 404613227, 429551030, 454926373, 480676280, 506737023, 533041379, 559520739, 586104532, 612719819,
+ 639298867, 665764101, 692044954, 718069120, 743765156, 769064062, 793893410, 818192510, 841895640,
+ 864939671, 887267243, 908824605, 929558785, 949422426, 968375342, 986383128, 1003413393, 1019433821,
+ 1034427350, 1048371873, 1061257817, 1073079562, 1083838763, 1093544388, 1102204732, 1109843920, 1116483171,
+ 1122153769, 1126889366, 1130731703, 1133726105, 1135920322, 1137368676, 1138125139, 1138249333, 1137797435,
+ 1136832092, 1135413661, 1133604477, 1131468200, 1129067483, 1126468580, 1123733695, 1120926768, 1118121453,
+ 1115661504, 1112733456, 1110039679, 1107592275, 1105388417, 1103424195, 1101694785, 1100194540, 1098917076,
+ 1097855409, 1097002014, 1096348961, 1095887953, 1095610427, 1095507566, 1095570351, 1095789547, 1096155725,
+ 1096659227, 1097290187, 1098038501, 1098893850, 1099845706, 1100883348, 1101995893, 1103172315, 1104401472,
+ 1105672121, 1106972938, 1108292669, -1109619302, -1110942189, -1112249205, -1113528884, -1114769580, -1115959638,
+ -1117087420, -1118141328, -1119109856, -1119981619, -1120745408, -1121390225, -1121905319, -1122280224, -1122504764,
+ -1122569097, -1122463704, -1122179448, -1121707579, -1121039818, -1120168401, -1119086203, -1117786804, -1116264645,
+ -1114515111, -1112534671, -1110320979, -1107872954, -1105190944, -1102290376, -1098369607, -1094349090, -1089850335,
+ -1084803470, -1079152632, -1072839707, -1065811535, -1058014404, -1049399648, -1039922082, -1029539502, -1018216878,
+ -1005918442, -992617105, -978287110, -962909114, -946468188, -928955851, -910372331, -890723372, -870025772,
+ -848301812, -825588219, -801924529, -777362543, -751959302, -725776798, -698887464, -671358557, -643273732,
+ -614708529, -585759042, -556515015, -527075925, -497538887, -468010517, -438598442, -409412725, -380564000,
+ -352163661, -324321484, -297140687, -270721761, -245158912, -220540161, -196946958, -174455223, -153136078,
+ -133056674, -114280750, -96868231, -80874056, -66345855, -53320577, -41820223, -31847346, -23380692,
+ -16371397, -10739000, -6256916 };
+# else
+# define MDCT_WINDOW_FS_24000_frame_ms_50 NULL
+# endif
+# ifdef SUBSET_SWB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_50[280] = {
+ 882763, 1521118, 2358563, 3425984, 4762639, 6395771, 8362131, 10689006, 13418692,
+ 16576000, 20193865, 24299300, 28928500, 34104984, 39865074, 46229302, 53228467, 60887056,
+ 69236180, 78292965, 88087142, 98634050, 109959733, 122081209, 135019424, 148782425, 163392710,
+ 178855011, 195181305, 212377526, 230451659, 249395809, 269219382, 289915225, 311477904, 333897457,
+ 357170677, 381274098, 406199848, 431929301, 458441926, 485710203, 513718369, 542430861, 571822196,
+ 601857045, 632504350, 663719412, 695470641, 727711424, 760403450, 793496784, 826949741, 860710772,
+ 894737379, 928972875, 963373530, 997882662, 1032450522, 1067021806, 1101552211, 1135977909, 1170251366,
+ 1204317771, 1238127288, 1271622131, 1304759595, 1337479850, 1369736833, 1401482421, 1432674669, 1463259078,
+ 1493196881, 1522440628, 1550955893, 1578698536, 1605635690, 1631726882, 1656947594, 1681264014, 1704659250,
+ 1727103999, 1748576205, 1769054798, 1788533700, 1806990078, 1824418644, 1840812466, 1856170505, 1870488908,
+ 1883781944, 1896047096, 1907297858, 1917548829, 1926819646, 1935123035, 1942490021, 1948939055, 1954502859,
+ 1959211322, 1963101243, 1966202102, 1968559589, 1970206964, 1971189283, 1971546464, 1971324022, 1970559672,
+ 1969305529, 1967600289, 1965492731, 1963026251, 1960251018, 1957207403, 1953949375, 1950518787, 1946965804,
+ 1943332468, 1939669743, 1936018211, 1933074896, 1929170790, 1925511708, 1922091318, 1918913458, 1915970631,
+ 1913265545, 1910789617, 1908544525, 1906520767, 1904719178, 1903129502, 1901751868, 1900575443, 1899599816,
+ 1898813735, 1898216400, 1897796234, 1897552155, 1897472330, 1897555435, 1897789418, 1898172732, 1898693091,
+ 1899348726, 1900127098, 1901026195, 1902033230, 1903145941, 1904351313, 1905646871, 1907019391, 1908466229,
+ 1909973977, 1911539869, 1913150363, 1914802598, 1916482920, 1918188394, 1919905292, -1921630629, -1923350609,
+ -1925062194, -1926751519, -1928415501, -1930040212, -1931622556, -1933148598, -1934615259, -1936008644, -1937325739,
+ -1938552759, -1939686835, -1940714349, -1941632651, -1942428351, -1943099088, -1943631764, -1944024336, -1944264050,
+ -1944349204, -1944267410, -1944017355, -1943587051, -1942975631, -1942171601, -1941174620, -1939973809, -1938569504,
+ -1936951577, -1935121231, -1933069293, -1930798023, -1928299406, -1925576914, -1922623868, -1919445128, -1916035514,
+ -1912401346, -1908538993, -1903226832, -1898165387, -1892651677, -1886636702, -1880083188, -1872945708, -1865186866,
+ -1856760038, -1847633035, -1837760249, -1827110036, -1815644193, -1803335041, -1790145270, -1776055593, -1761033530,
+ -1745059396, -1728108424, -1710167501, -1691212572, -1671237793, -1650226116, -1628174600, -1605075941, -1580936677,
+ -1555754529, -1529546654, -1502320930, -1474101256, -1444909741, -1414780308, -1383738492, -1351831573, -1319095487,
+ -1285577912, -1251324682, -1216394344, -1180827594, -1144691880, -1108040592, -1070930654, -1033434550, -995621142,
+ -957552560, -919309430, -880954958, -842572374, -804234470, -766025822, -728021485, -690307576, -652960034,
+ -616065598, -579699451, -543943367, -508866771, -474546527, -441046910, -408438534, -376778154, -346129113,
+ -316541929, -288074358, -260771792, -234687576, -209863469, -186348825, -164181088, -143404068, -124048067,
+ -106147028, -89718620, -74780184, -61329654, -49360094, -38842904, -29739589, -21991349, -15513048,
+ -10180154 };
+# else
+# define MDCT_WINDOW_FS_32000_frame_ms_50 NULL
+# endif
+# ifdef SUBSET_FB
+RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_50[420] = {
+ 641452, 963468, 1344309, 1798864, 2336113, 2963727, 3690212, 4523143, 5470567,
+ 6539876, 7738462, 9075874, 10560639, 12200013, 14000287, 15968479, 18112467, 20440430,
+ 22959153, 25675517, 28597257, 31731569, 35084700, 38662325, 42471171, 46518292, 50811124,
+ 55354756, 60154720, 65216952, 70547205, 76150562, 82031461, 88195322, 94647798, 101393537,
+ 108435354, 115776449, 123420676, 131372779, 139634617, 148207504, 157093536, 166295700, 175815910,
+ 185653595, 195807761, 206278987, 217068929, 228177014, 239600679, 251337195, 263385931, 275745715,
+ 288413583, 301384760, 314655039, 328222340, 342083665, 356233498, 370664518, 385372123, 400351243,
+ 415596618, 431100575, 446855251, 462853492, 479088256, 495551477, 512233512, 529124734, 546216403,
+ 563499351, 580963667, 598598648, 616393743, 634338212, 652420945, 670630244, 688955012, 707384418,
+ 725906000, 744507517, 763176760, 781901922, 800670867, 819470287, 838286395, 857107788, 875922821,
+ 894718707, 913481313, 932196408, 950852353, 969437415, 987938553, 1006342043, 1024635125, 1042806406,
+ 1060844237, 1078734559, 1096464849, 1114023247, 1131399453, 1148583332, 1165562052, 1182324038, 1198858240,
+ 1215154081, 1231201466, 1246990634, 1262512157, 1277756598, 1292714571, 1307377034, 1321735176, 1335781943,
+ 1349510011, 1362912058, 1375982854, 1388718627, 1401109382, 1413152613, 1424839949, 1436168435, 1447135603,
+ 1457737882, 1467971469, 1477831821, 1487317959, 1496429995, 1505166563, 1513525606, 1521507797, 1529115290,
+ 1536350460, 1543213224, 1549704472, 1555827692, 1561587898, 1566989343, 1572034920, 1576728782, 1581076815,
+ 1585086027, 1588761389, 1592109107, 1595136511, 1597852394, 1600264963, 1602381209, 1604209606, 1605759882,
+ 1607041997, 1608065019, 1608838122, 1609371538, 1609676596, 1609763199, 1609640908, 1609320042, 1608811796,
+ 1608127979, 1607278811, 1606274326, 1605125864, 1603845218, 1602443629, 1600931810, 1599320348, 1597621250,
+ 1595846595, 1594007402, 1592114826, 1590179414, 1588213076, 1586227163, 1584231653, 1582234964, 1580207977,
+ 1578973545, 1576735799, 1574650444, 1572657612, 1570752789, 1568935343, 1567204832, 1565560739, 1564002460,
+ 1562529304, 1561140497, 1559835185, 1558612434, 1557471243, 1556410547, 1555429220, 1554526076, 1553699872,
+ 1552949321, 1552273100, 1551669839, 1551138129, 1550676530, 1550283581, 1549957792, 1549697644, 1549501594,
+ 1549368091, 1549295559, 1549282400, 1549326998, 1549427723, 1549582929, 1549790946, 1550050083, 1550358639,
+ 1550714889, 1551117086, 1551563464, 1552052237, 1552581604, 1553149738, 1553754795, 1554394911, 1555068212,
+ 1555772800, 1556506765, 1557268182, 1558055112, 1558865609, 1559697712, 1560549450, 1561418844, 1562303905,
+ 1563202640, 1564113045, 1565033113, 1565960825, 1566894119, 1567830370, -1568770400, -1569707772, -1570643299,
+ -1571574337, -1572498793, -1573414613, -1574319739, -1575212113, -1576089676, -1576950365, -1577792121, -1578612885,
+ -1579410602, -1580183223, -1580928704, -1581645010, -1582330113, -1582982003, -1583598681, -1584178165, -1584718489,
+ -1585217707, -1585673898, -1586085163, -1586449622, -1586765423, -1587030743, -1587243787, -1587402781, -1587505982,
+ -1587551679, -1587538195, -1587463877, -1587327103, -1587126293, -1586859906, -1586526431, -1586124397, -1585652387,
+ -1585109032, -1584493010, -1583803053, -1583037961, -1582196603, -1581277917, -1580280911, -1579204680, -1578048412,
+ -1576811384, -1575492968, -1574092640, -1572609980, -1571044684, -1569396562, -1567665543, -1565851670, -1563955090,
+ -1561975794, -1559909960, -1557699231, -1554579493, -1551951859, -1549122074, -1546121016, -1542941389, -1539572601,
+ -1536005010, -1532229275, -1528234689, -1524011122, -1519548313, -1514837211, -1509868869, -1504633300, -1499121016,
+ -1493323395, -1487232726, -1480841309, -1474140699, -1467123022, -1459782240, -1452112311, -1444106817, -1435759114,
+ -1427063276, -1418015155, -1408610288, -1398843935, -1388711462, -1378209682, -1367336091, -1356088102, -1344462791,
+ -1332458664, -1320075617, -1307313612, -1294173092, -1280654545, -1266760135, -1252493498, -1237857298, -1222855659,
+ -1207493934, -1191778366, -1175716859, -1159315327, -1142581197, -1125524357, -1108155092, -1090483582, -1072519662,
+ -1054273467, -1035757912, -1016986859, -997971439, -978723129, -959255645, -939584189, -919723670, -899686034,
+ -879484158, -859140109, -838667380, -818082710, -797402257, -776643501, -755824703, -734962210, -714073915,
+ -693179322, -672297393, -651446511, -630646657, -609917124, -589277150, -568746490, -548345449, -528092326,
+ -508008241, -488111645, -468421183, -448956496, -429734434, -410773661, -392090517, -373702005, -355624406,
+ -337873208, -320463322, -303409145, -286724555, -270422942, -254517317, -239020241, -223943842, -209300003,
+ -195100311, -181356034, -168078124, -155277193, -142963461, -131146681, -119836028, -109039985, -98766166,
+ -89021184, -79810417, -71137840, -63005796, -55414797, -48363340, -41847826, -35862016, -30397367,
+ -25442735, -20983937, -17003804, -13482292, -10414308, -8112352 };
+# else
+# define MDCT_WINDOW_FS_48000_frame_ms_50 NULL
+# endif
+#endif
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6] = {
+ MDCT_WINDOW_FS_8000_frame_ms_50, MDCT_WINDOW_FS_16000_frame_ms_50, MDCT_WINDOW_FS_24000_frame_ms_50, MDCT_WINDOW_FS_32000_frame_ms_50, MDCT_WINDOW_FS_48000_frame_ms_50, NULL };
+#else
+RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6] = {LowDelayShapes_n960_N40_5ms, LowDelayShapes_n960_N80_5ms,
+ LowDelayShapes_n960_N120_5ms, LowDelayShapes_n960_N160_5ms,
+ LowDelayShapes_n960_N240_5ms, NULL};
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6] = {40, 80, 120, 160, 240, 480};
+# else
+RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5] = {40, 80, 120, 160, 240};
+# endif
+
+RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ] = {0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6] = {
+ MDCT_WINDOW_FS_8000_frame_ms_25, MDCT_WINDOW_FS_16000_frame_ms_25, MDCT_WINDOW_FS_24000_frame_ms_25, MDCT_WINDOW_FS_32000_frame_ms_25, MDCT_WINDOW_FS_48000_frame_ms_25, NULL };
+#else
+RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6] = {
+ LowDelayShapes_n960_N40_2_5ms, LowDelayShapes_n960_N80_2_5ms, LowDelayShapes_n960_N120_2_5ms,
+ LowDelayShapes_n960_N160_2_5ms, LowDelayShapes_n960_N240_2_5ms, NULL};
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_HR[6] = {12, 74, 137, 200, 266, 333};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_HR[6] = {74, 137, 200, 266, 333, 400};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_HR[6] = {12, 74, 137, 200, 266, 333};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_HR[6] = {74, 137, 200, 266, 333, 400};
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2] = {tns_subdiv_startfreq_48k_HR, tns_subdiv_startfreq_96k_HR};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2] = {tns_subdiv_stopfreq_48k_HR, tns_subdiv_stopfreq_96k_HR};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms_HR[4] = {6, 53, 100, 150};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms_HR[4] = {53, 100, 150, 200};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_5ms_HR[4] = {6, 53, 100, 150};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_5ms_HR[4] = {53, 100, 150, 200};
+
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2] = {tns_subdiv_startfreq_48k_5ms_HR,
+ tns_subdiv_startfreq_96k_5ms_HR};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2] = {tns_subdiv_stopfreq_48k_5ms_HR,
+ tns_subdiv_stopfreq_96k_5ms_HR};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms_HR[2] = {3, 51};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms_HR[2] = {51, 100};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_2_5ms_HR[2] = {3, 51};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_2_5ms_HR[2] = {51, 100};
+
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2] = {tns_subdiv_startfreq_48k_2_5ms_HR,
+ tns_subdiv_startfreq_96k_2_5ms_HR};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2] = {tns_subdiv_stopfreq_48k_2_5ms_HR,
+ tns_subdiv_stopfreq_96k_2_5ms_HR};
+# endif
+
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_8k[6] = {12, 34, 57, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k[6] = {34, 57, 80, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_16k[6] = {12, 61, 110, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k[6] = {61, 110, 160, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_24k[6] = {12, 88, 164, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k[6] = {88, 164, 240, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_32k[6] = {12, 61, 110, 160, 213, 266};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k[6] = {61, 110, 160, 213, 266, 320};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k[6] = {12, 74, 137, 200, 266, 333};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k[6] = {74, 137, 200, 266, 333, 400};
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_startfreq_8k, tns_subdiv_startfreq_16k, tns_subdiv_startfreq_24k, tns_subdiv_startfreq_32k,
+ tns_subdiv_startfreq_48k};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_stopfreq_8k, tns_subdiv_stopfreq_16k, tns_subdiv_stopfreq_24k, tns_subdiv_stopfreq_32k,
+ tns_subdiv_stopfreq_48k};
+
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_5ms[4] = {6, 23, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_5ms[4] = {23, 40, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_5ms[4] = {6, 43, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_5ms[4] = {43, 80, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_5ms[4] = {6, 63, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_5ms[4] = {63, 120, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_5ms[4] = {6, 43, 80, 120};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_5ms[4] = {43, 80, 120, 160};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms[4] = {6, 53, 100, 150};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms[4] = {53, 100, 150, 200};
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_startfreq_8k_5ms, tns_subdiv_startfreq_16k_5ms, tns_subdiv_startfreq_24k_5ms,
+ tns_subdiv_startfreq_32k_5ms, tns_subdiv_startfreq_48k_5ms};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_stopfreq_8k_5ms, tns_subdiv_stopfreq_16k_5ms, tns_subdiv_stopfreq_24k_5ms, tns_subdiv_stopfreq_32k_5ms,
+ tns_subdiv_stopfreq_48k_5ms};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_2_5ms[2] = {3, 11};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_2_5ms[2] = {11, 20};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_2_5ms[2] = {3, 21};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_2_5ms[2] = {21, 40};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_2_5ms[2] = {3, 31};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_2_5ms[2] = {31, 60};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_2_5ms[2] = {3, 41};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_2_5ms[2] = {41, 80};
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms[2] = {3, 51};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms[2] = {51, 100};
+
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_startfreq_8k_2_5ms, tns_subdiv_startfreq_16k_2_5ms, tns_subdiv_startfreq_24k_2_5ms,
+ tns_subdiv_startfreq_32k_2_5ms, tns_subdiv_startfreq_48k_2_5ms};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER] = {
+ tns_subdiv_stopfreq_8k_2_5ms, tns_subdiv_stopfreq_16k_2_5ms, tns_subdiv_stopfreq_24k_2_5ms,
+ tns_subdiv_stopfreq_32k_2_5ms, tns_subdiv_stopfreq_48k_2_5ms};
+
+#ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_7_5ms[6] = {9, 26, 43, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_7_5ms[6] = {26, 43, 60, 0, 0, 0};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_7_5ms[6] = {9, 46, 83, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_7_5ms[6] = {46, 83, 120, 0, 0, 0};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_7_5ms[6] = {9, 66, 123, 0, 0, 0};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_7_5ms[6] = {66, 123, 180, 0, 0, 0};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_7_5ms[6] = {9, 46, 82, 120, 159, 200};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_7_5ms[6] = {46, 82, 120, 159, 200, 240};
+
+RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_7_5ms[6] = {9, 56, 103, 150, 200, 250};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_7_5ms[6] = {56, 103, 150, 200, 250, 300};
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_7_5ms[6] = {9, 56, 103, 150, 200, 250};
+RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_7_5ms[6] = {56, 103, 150, 200, 250, 300};
+# endif
+
+RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[] = {
+ tns_subdiv_startfreq_8k_7_5ms, tns_subdiv_startfreq_16k_7_5ms, tns_subdiv_startfreq_24k_7_5ms,
+ tns_subdiv_startfreq_32k_7_5ms, tns_subdiv_startfreq_48k_7_5ms
+# ifdef ENABLE_HR_MODE
+ , tns_subdiv_startfreq_96k_7_5ms
+# endif
+};
+RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[] = {
+ tns_subdiv_stopfreq_8k_7_5ms, tns_subdiv_stopfreq_16k_7_5ms, tns_subdiv_stopfreq_24k_7_5ms,
+ tns_subdiv_stopfreq_32k_7_5ms, tns_subdiv_stopfreq_48k_7_5ms
+# ifdef ENABLE_HR_MODE
+ , tns_subdiv_stopfreq_96k_7_5ms
+# endif
+};
+# endif
+
+RAM_ALIGN const Word16 Tab_esc_nb[4] = {0 << (NBITS_CONTEXT + NBITS_RATEQ), 1 << (NBITS_CONTEXT + NBITS_RATEQ),
+ 2 << (NBITS_CONTEXT + NBITS_RATEQ), 3 << (NBITS_CONTEXT + NBITS_RATEQ)};
+RAM_ALIGN const Word8 ari_spec_lookup[4096] = {
+ 0x01, 0x27, 0x07, 0x19, 0x16, 0x16, 0x1C, 0x16, 0x16, 0x16, 0x16, 0x1C, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x28, 0x2B,
+ 0x2E, 0x31, 0x34, 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x00, 0x39, 0x26, 0x16, 0x00, 0x08, 0x09, 0x0B, 0x2F, 0x0E,
+ 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x3B, 0x3B, 0x26, 0x16, 0x16, 0x1A, 0x2E, 0x1D, 0x1E, 0x20, 0x21, 0x23, 0x24,
+ 0x24, 0x24, 0x26, 0x00, 0x3B, 0x17, 0x16, 0x2E, 0x2E, 0x2D, 0x2F, 0x30, 0x32, 0x32, 0x12, 0x36, 0x36, 0x36, 0x26,
+ 0x3B, 0x3B, 0x3B, 0x16, 0x00, 0x3E, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x14, 0x14, 0x14, 0x15, 0x3B, 0x3B, 0x27,
+ 0x1C, 0x1C, 0x3F, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x15, 0x3B, 0x3B, 0x27, 0x1C, 0x1C, 0x06,
+ 0x06, 0x06, 0x02, 0x12, 0x3D, 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x35, 0x36, 0x14, 0x26,
+ 0x26, 0x39, 0x27, 0x27, 0x27, 0x07, 0x18, 0x22, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x26, 0x39, 0x39, 0x3B, 0x07, 0x07, 0x07, 0x2A,
+ 0x2A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x04, 0x04, 0x05, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x07, 0x19, 0x19, 0x19, 0x22, 0x04, 0x04, 0x04, 0x04,
+ 0x05, 0x17, 0x17, 0x27, 0x07, 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x27, 0x27, 0x27, 0x27, 0x07, 0x07,
+ 0x2A, 0x00, 0x19, 0x16, 0x16, 0x16, 0x1C, 0x22, 0x1F, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
+ 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x28, 0x08, 0x09, 0x31, 0x31, 0x34, 0x11, 0x11, 0x11, 0x04, 0x00,
+ 0x14, 0x11, 0x3C, 0x28, 0x28, 0x08, 0x2B, 0x1B, 0x31, 0x31, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x2A, 0x2A, 0x11, 0x39,
+ 0x39, 0x28, 0x08, 0x1A, 0x1B, 0x31, 0x0C, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x00, 0x26, 0x24, 0x01, 0x08, 0x08, 0x2B,
+ 0x09, 0x0B, 0x31, 0x0C, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x3D, 0x24, 0x27, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34,
+ 0x1E, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x32, 0x12, 0x19, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, 0x1E, 0x0E, 0x0E,
+ 0x12, 0x05, 0x05, 0x05, 0x3D, 0x12, 0x17, 0x2B, 0x2B, 0x2B, 0x09, 0x31, 0x34, 0x03, 0x0E, 0x0E, 0x32, 0x32, 0x32,
+ 0x32, 0x3D, 0x11, 0x18, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
+ 0x2B, 0x2B, 0x2B, 0x2B, 0x09, 0x0B, 0x34, 0x34, 0x0E, 0x0E, 0x11, 0x3D, 0x3D, 0x3D, 0x36, 0x11, 0x27, 0x2D, 0x2D,
+ 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C, 0x1B, 0x1D,
+ 0x34, 0x30, 0x34, 0x34, 0x11, 0x11, 0x11, 0x11, 0x02, 0x11, 0x07, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
+ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x09, 0x1B, 0x1B, 0x0C, 0x34, 0x0E, 0x0E, 0x3A, 0x29,
+ 0x29, 0x29, 0x06, 0x11, 0x25, 0x09, 0x09, 0x09, 0x1B, 0x0B, 0x31, 0x0C, 0x34, 0x0E, 0x0E, 0x0E, 0x32, 0x00, 0x35,
+ 0x11, 0x1C, 0x34, 0x34, 0x31, 0x34, 0x0C, 0x34, 0x1E, 0x0E, 0x0E, 0x11, 0x02, 0x02, 0x02, 0x26, 0x26, 0x22, 0x1F,
+ 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x1F, 0x13, 0x2C, 0x2C, 0x3E, 0x1E,
+ 0x20, 0x3A, 0x23, 0x24, 0x24, 0x26, 0x00, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x2D, 0x2F, 0x30, 0x21, 0x23, 0x23,
+ 0x24, 0x26, 0x26, 0x26, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x3E, 0x1E, 0x0F, 0x32, 0x35, 0x35, 0x36, 0x15, 0x15,
+ 0x15, 0x3B, 0x07, 0x07, 0x07, 0x22, 0x1E, 0x1E, 0x30, 0x21, 0x3A, 0x12, 0x12, 0x38, 0x17, 0x17, 0x17, 0x3B, 0x07,
+ 0x07, 0x18, 0x22, 0x22, 0x06, 0x06, 0x3A, 0x35, 0x36, 0x36, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22,
+ 0x06, 0x06, 0x21, 0x3A, 0x35, 0x36, 0x3D, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, 0x22, 0x33, 0x33,
+ 0x35, 0x36, 0x38, 0x38, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x07,
+ 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x39, 0x39, 0x27, 0x18, 0x18, 0x18, 0x2A, 0x16, 0x16, 0x1C,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x29,
+ 0x29, 0x29, 0x29, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x2A, 0x19, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x29,
+ 0x27, 0x27, 0x18, 0x19, 0x19, 0x19, 0x16, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1F, 0x13, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x0B, 0x2F, 0x20, 0x32, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x27,
+ 0x3B, 0x22, 0x1A, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x32, 0x12, 0x12, 0x14, 0x39, 0x39, 0x39, 0x3B, 0x3B, 0x22, 0x1B,
+ 0x1B, 0x0B, 0x0C, 0x30, 0x32, 0x3A, 0x3D, 0x3D, 0x38, 0x39, 0x39, 0x39, 0x3B, 0x27, 0x22, 0x2D, 0x2D, 0x0C, 0x1E,
+ 0x20, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x39, 0x00, 0x3B, 0x27, 0x22, 0x3F, 0x3F, 0x03, 0x20, 0x3A, 0x12, 0x12,
+ 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x1F, 0x1F, 0x03, 0x03, 0x21, 0x3A, 0x12, 0x12, 0x14, 0x15, 0x15,
+ 0x15, 0x3B, 0x07, 0x07, 0x07, 0x1F, 0x06, 0x06, 0x33, 0x33, 0x35, 0x36, 0x36, 0x26, 0x39, 0x39, 0x39, 0x27, 0x07,
+ 0x07, 0x2A, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x33, 0x35, 0x35, 0x36, 0x38, 0x38, 0x39, 0x3B, 0x3B, 0x3B, 0x07, 0x18, 0x18, 0x19, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x36, 0x15,
+ 0x15, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x3B, 0x07, 0x07, 0x07, 0x2A,
+ 0x16, 0x16, 0x1C, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x18, 0x18, 0x18, 0x19, 0x1C, 0x1C, 0x22,
+ 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
+ 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
+ 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x3C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00,
+ 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C,
+ 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x13,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x13, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00,
+ 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17] = {
+ {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824, 834},
+ {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328, 341},
+ {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727, 749, 764},
+ {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866, 881, 890},
+ {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586, 607, 622},
+ {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524, 545, 561},
+ {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807, 825, 836},
+ {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346, 362},
+ {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014, 1017, 1018, 1019},
+ {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002, 1005, 1007},
+ {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247, 257},
+ {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978, 984, 987},
+ {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944, 954, 959},
+ {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576, 592},
+ {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857, 870, 878},
+ {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857, 872, 881},
+ {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217},
+ {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745, 762, 774},
+ {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659, 683, 699},
+ {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
+ {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574, 593},
+ {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506, 524},
+ {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236, 250},
+ {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478, 494},
+ {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314, 329},
+ {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262, 276},
+ {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010, 1012, 1013},
+ {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998, 1002, 1004},
+ {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219},
+ {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964, 971, 975},
+ {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904, 916, 923},
+ {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90},
+ {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832, 849, 859},
+ {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813, 831, 842},
+ {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178},
+ {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712, 732, 745},
+ {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605, 626, 641},
+ {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88},
+ {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524, 543},
+ {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385, 401},
+ {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019, 1020, 1021, 1022},
+ {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470, 484},
+ {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292, 307},
+ {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008, 1010, 1011},
+ {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986, 991, 993},
+ {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963, 971, 975},
+ {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987, 992, 994},
+ {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926, 936, 942},
+ {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877, 891, 899},
+ {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953, 960, 964},
+ {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788, 807, 819},
+ {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730, 751, 765},
+ {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895, 906, 912},
+ {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678, 700, 715},
+ {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588, 612, 629},
+ {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023},
+ {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548, 565},
+ {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453, 471},
+ {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756, 776, 789},
+ {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431, 448},
+ {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430},
+ {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616, 640, 658},
+ {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937, 946, 951},
+ {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909, 921, 928}};
+
+RAM_ALIGN const UWord16 ari_spec_freq[64][17] = {
+ {1, 1, 175, 48, 1, 1, 109, 36, 171, 109, 47, 20, 49, 36, 20, 10, 190},
+ {18, 26, 17, 10, 27, 37, 24, 16, 22, 32, 22, 14, 17, 26, 20, 13, 683},
+ {71, 92, 49, 25, 81, 102, 61, 33, 42, 57, 39, 23, 22, 30, 22, 15, 260},
+ {160, 130, 46, 18, 121, 123, 55, 24, 45, 55, 31, 15, 19, 24, 15, 9, 134},
+ {71, 73, 33, 18, 71, 76, 43, 26, 34, 44, 30, 20, 20, 27, 21, 15, 402},
+ {48, 60, 32, 19, 58, 68, 42, 27, 31, 42, 30, 21, 19, 27, 21, 16, 463},
+ {138, 109, 43, 18, 111, 112, 53, 25, 46, 55, 32, 17, 21, 27, 18, 11, 188},
+ {16, 24, 22, 17, 24, 36, 31, 25, 20, 30, 25, 20, 15, 22, 19, 16, 662},
+ {579, 150, 12, 2, 154, 73, 10, 2, 14, 11, 3, 1, 3, 3, 1, 1, 5},
+ {398, 184, 25, 5, 176, 114, 23, 6, 25, 23, 8, 3, 6, 6, 3, 2, 17},
+ {13, 21, 18, 11, 20, 29, 22, 15, 14, 20, 16, 12, 10, 14, 12, 10, 767},
+ {281, 183, 37, 9, 171, 139, 37, 10, 35, 36, 15, 6, 9, 10, 6, 3, 37},
+ {198, 164, 46, 13, 154, 147, 51, 16, 43, 49, 24, 10, 13, 16, 10, 5, 65},
+ {1, 1, 93, 44, 1, 1, 72, 38, 86, 70, 43, 25, 40, 36, 25, 16, 432},
+ {133, 141, 64, 28, 117, 122, 59, 27, 39, 48, 29, 15, 15, 20, 13, 8, 146},
+ {128, 125, 49, 18, 123, 134, 59, 23, 49, 59, 32, 15, 19, 24, 15, 9, 143},
+ {1, 1, 23, 17, 1, 1, 23, 18, 20, 21, 18, 15, 15, 17, 14, 12, 807},
+ {70, 96, 63, 38, 89, 112, 65, 36, 37, 47, 32, 20, 17, 23, 17, 12, 250},
+ {55, 75, 45, 25, 68, 90, 58, 33, 39, 54, 39, 25, 22, 31, 24, 16, 325},
+ {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 993},
+ {34, 51, 38, 24, 49, 69, 52, 35, 34, 47, 37, 27, 21, 31, 25, 19, 431},
+ {30, 43, 32, 22, 43, 59, 45, 31, 30, 42, 34, 25, 19, 28, 23, 18, 500},
+ {9, 15, 14, 13, 14, 22, 21, 18, 13, 20, 18, 16, 11, 17, 15, 14, 774},
+ {30, 44, 31, 20, 41, 58, 42, 28, 28, 39, 30, 22, 18, 26, 21, 16, 530},
+ {15, 23, 20, 15, 22, 33, 28, 22, 18, 26, 23, 18, 13, 20, 18, 15, 695},
+ {11, 17, 16, 13, 17, 26, 23, 19, 15, 22, 20, 17, 12, 18, 16, 14, 748},
+ {448, 171, 20, 4, 178, 105, 18, 4, 23, 20, 7, 2, 5, 5, 2, 1, 11},
+ {332, 188, 29, 6, 186, 133, 29, 7, 30, 30, 11, 4, 6, 7, 4, 2, 20},
+ {8, 13, 13, 11, 13, 20, 18, 16, 12, 17, 16, 13, 10, 14, 13, 12, 805},
+ {239, 176, 42, 11, 163, 145, 44, 13, 39, 42, 19, 7, 11, 13, 7, 4, 49},
+ {165, 145, 49, 16, 138, 139, 55, 20, 47, 54, 28, 12, 16, 20, 12, 7, 101},
+ {3, 5, 5, 5, 5, 7, 7, 7, 4, 7, 7, 6, 4, 6, 6, 6, 934},
+ {115, 122, 52, 22, 111, 125, 61, 27, 45, 57, 34, 17, 19, 25, 17, 10, 165},
+ {107, 114, 51, 21, 106, 122, 61, 28, 46, 58, 35, 18, 20, 26, 18, 11, 182},
+ {6, 10, 10, 9, 10, 15, 15, 14, 9, 14, 13, 12, 8, 12, 11, 10, 846},
+ {72, 88, 50, 26, 84, 102, 60, 32, 41, 53, 36, 21, 20, 27, 20, 13, 279},
+ {45, 63, 45, 30, 61, 83, 58, 36, 34, 47, 34, 23, 19, 27, 21, 15, 383},
+ {1, 1, 7, 7, 1, 1, 8, 8, 6, 8, 7, 7, 6, 7, 7, 6, 936},
+ {29, 44, 35, 24, 42, 62, 48, 34, 30, 43, 35, 26, 19, 29, 24, 19, 481},
+ {20, 31, 25, 17, 30, 43, 34, 25, 22, 32, 26, 21, 16, 23, 20, 16, 623},
+ {742, 103, 5, 1, 108, 38, 4, 1, 7, 5, 2, 1, 2, 1, 1, 1, 2},
+ {42, 52, 27, 16, 49, 58, 36, 23, 27, 36, 26, 18, 17, 24, 19, 14, 540},
+ {13, 20, 18, 15, 19, 29, 26, 21, 17, 25, 22, 18, 13, 19, 17, 15, 717},
+ {501, 169, 19, 4, 155, 88, 16, 4, 19, 16, 6, 2, 5, 4, 2, 1, 13},
+ {445, 136, 22, 6, 158, 98, 23, 7, 31, 28, 10, 4, 9, 9, 5, 2, 31},
+ {285, 157, 37, 10, 161, 129, 39, 12, 40, 42, 18, 7, 12, 14, 8, 4, 49},
+ {349, 179, 33, 8, 162, 121, 31, 9, 31, 30, 12, 5, 8, 9, 5, 2, 30},
+ {199, 156, 47, 15, 146, 137, 50, 17, 44, 49, 24, 10, 15, 17, 10, 6, 82},
+ {141, 134, 50, 18, 128, 135, 58, 22, 48, 57, 31, 14, 18, 23, 14, 8, 125},
+ {243, 194, 56, 17, 139, 126, 45, 16, 33, 36, 18, 8, 10, 12, 7, 4, 60},
+ {91, 106, 51, 23, 99, 117, 63, 30, 45, 59, 37, 20, 20, 27, 19, 12, 205},
+ {107, 94, 41, 20, 92, 97, 52, 28, 42, 53, 34, 20, 21, 29, 21, 14, 259},
+ {168, 171, 68, 25, 121, 123, 55, 24, 34, 41, 24, 12, 13, 16, 11, 6, 112},
+ {67, 80, 44, 23, 76, 94, 57, 31, 41, 54, 37, 23, 21, 30, 22, 15, 309},
+ {46, 63, 39, 23, 58, 78, 52, 32, 36, 49, 37, 24, 21, 30, 24, 17, 395},
+ {848, 70, 2, 1, 75, 16, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1},
+ {36, 52, 35, 22, 48, 67, 48, 32, 32, 45, 35, 24, 20, 29, 23, 17, 459},
+ {24, 37, 29, 20, 35, 51, 41, 29, 26, 38, 31, 24, 18, 27, 23, 18, 553},
+ {85, 97, 48, 23, 91, 110, 61, 30, 45, 58, 37, 21, 21, 29, 20, 13, 235},
+ {22, 33, 27, 20, 33, 48, 39, 30, 26, 37, 30, 23, 17, 25, 21, 17, 576},
+ {1, 1, 54, 33, 1, 1, 49, 32, 49, 47, 35, 25, 30, 30, 24, 18, 594},
+ {45, 64, 43, 25, 62, 81, 56, 35, 37, 51, 38, 26, 22, 31, 24, 18, 366},
+ {247, 148, 38, 12, 154, 130, 42, 14, 44, 46, 21, 9, 15, 17, 9, 5, 73},
+ {231, 136, 41, 15, 134, 119, 47, 19, 44, 49, 25, 12, 17, 20, 12, 7, 96}};
+
+RAM_ALIGN const UWord16 ari_spec_bits[64][17] = {
+ {20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, 5289, 6619, 9105, 11629, 8982, 9892, 11629, 13677, 4977},
+ {11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, 11348, 10240, 11348, 12683, 12109, 10854, 11629, 12902,
+ 1197},
+ {7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, 9437, 8535, 9656, 11216, 11348, 10431, 11348, 12479, 4051},
+ {5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, 9233, 8640, 10334, 12479, 11781, 11090, 12479, 13988, 6009},
+ {7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, 10061, 9300, 10431, 11629, 11629, 10742, 11485, 12479, 2763},
+ {9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, 10334, 9437, 10431, 11485, 11781, 10742, 11485, 12288, 2346},
+ {5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, 9168, 8640, 10240, 12109, 11485, 10742, 11940, 13396, 5009},
+ {12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, 11629, 10431, 10970, 11629, 12479, 11348, 11781, 12288,
+ 1289},
+ {1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, 12683, 13396, 17234, 20480, 17234, 17234, 20480, 20480, 15725},
+ {2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, 10970, 11216, 14336, 17234, 15186, 15186, 17234, 18432, 12109},
+ {12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, 12683, 11629, 12288, 13138, 13677, 12683, 13138, 13677,
+ 854},
+ {3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, 9976, 9892, 12479, 15186, 13988, 13677, 15186, 17234, 9812},
+ {4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, 9368, 8982, 11090, 13677, 12902, 12288, 13677, 15725, 8147},
+ {20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, 7320, 7928, 9368, 10970, 9581, 9892, 10970, 12288, 2550},
+ {6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, 9656, 9042, 10531, 12479, 12479, 11629, 12902, 14336, 5756},
+ {6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, 8982, 8433, 10240, 12479, 11781, 11090, 12479, 13988, 5817},
+ {20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, 11629, 11485, 11940, 12479, 12479, 12109, 12683, 13138,
+ 704},
+ {7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, 9812, 9105, 10240, 11629, 12109, 11216, 12109, 13138, 4167},
+ {8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, 9656, 8694, 9656, 10970, 11348, 10334, 11090, 12288, 3391},
+ {20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432,
+ 91},
+ {10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, 10061, 9105, 9812, 10742, 11485, 10334, 10970, 11781, 2557},
+ {10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, 10431, 9437, 10061, 10970, 11781, 10635, 11216, 11940, 2119},
+ {13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, 12902, 11629, 11940, 12288, 13396, 12109, 12479, 12683,
+ 828},
+ {10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, 10635, 9656, 10431, 11348, 11940, 10854, 11485, 12288, 1946},
+ {12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, 11940, 10854, 11216, 11940, 12902, 11629, 11940, 12479,
+ 1146},
+ {13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, 12479, 11348, 11629, 12109, 13138, 11940, 12288, 12683,
+ 928},
+ {2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, 11216, 11629, 14731, 18432, 15725, 15725, 18432, 20480, 13396},
+ {3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, 10431, 10431, 13396, 16384, 15186, 14731, 16384, 18432, 11629},
+ {14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, 13138, 12109, 12288, 12902, 13677, 12683, 12902, 13138,
+ 711},
+ {4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, 9656, 9437, 11781, 14731, 13396, 12902, 14731, 16384, 8982},
+ {5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, 9105, 8694, 10635, 13138, 12288, 11629, 13138, 14731, 6844},
+ {17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, 16384, 14731, 14731, 15186, 16384, 15186, 15186, 15186,
+ 272},
+ {6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, 9233, 8535, 10061, 12109, 11781, 10970, 12109, 13677, 5394},
+ {6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, 9168, 8483, 9976, 11940, 11629, 10854, 11940, 13396, 5105},
+ {15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, 13988, 12683, 12902, 13138, 14336, 13138, 13396, 13677,
+ 565},
+ {7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, 9508, 8750, 9892, 11485, 11629, 10742, 11629, 12902, 3842},
+ {9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, 10061, 9105, 10061, 11216, 11781, 10742, 11485, 12479, 2906},
+ {20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, 15186, 14336, 14731, 14731, 15186, 14731, 14731, 15186,
+ 266},
+ {10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, 10431, 9368, 9976, 10854, 11781, 10531, 11090, 11781, 2233},
+ {11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, 11348, 10240, 10854, 11485, 12288, 11216, 11629, 12288,
+ 1469},
+ {952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, 14731, 15725, 18432, 20480, 18432, 20480, 20480, 20480, 18432},
+ {9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, 10742, 9892, 10854, 11940, 12109, 11090, 11781, 12683, 1891},
+ {12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, 12109, 10970, 11348, 11940, 12902, 11781, 12109, 12479,
+ 1054},
+ {2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, 11781, 12288, 15186, 18432, 15725, 16384, 18432, 20480, 12902},
+ {2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, 10334, 10635, 13677, 16384, 13988, 13988, 15725, 18432, 10334},
+ {3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, 9581, 9437, 11940, 14731, 13138, 12683, 14336, 16384, 8982},
+ {3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, 10334, 10431, 13138, 15725, 14336, 13988, 15725, 18432, 10431},
+ {4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, 9300, 8982, 11090, 13677, 12479, 12109, 13677, 15186, 7460},
+ {5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, 9042, 8535, 10334, 12683, 11940, 11216, 12683, 14336, 6215},
+ {4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, 10150, 9892, 11940, 14336, 13677, 13138, 14731, 16384, 8383},
+ {7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, 9233, 8433, 9812, 11629, 11629, 10742, 11781, 13138, 4753},
+ {6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, 9437, 8750, 10061, 11629, 11485, 10531, 11485, 12683, 4062},
+ {5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, 10061, 9508, 11090, 13138, 12902, 12288, 13396, 15186, 6539},
+ {8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, 9508, 8694, 9812, 11216, 11485, 10431, 11348, 12479, 3541},
+ {9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, 9892, 8982, 9812, 11090, 11485, 10431, 11090, 12109, 2815},
+ {558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480},
+ {9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, 10240, 9233, 9976, 11090, 11629, 10531, 11216, 12109, 2371},
+ {11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, 10854, 9733, 10334, 11090, 11940, 10742, 11216, 11940, 1821},
+ {7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, 9233, 8483, 9812, 11485, 11485, 10531, 11629, 12902, 4349},
+ {11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, 10854, 9812, 10431, 11216, 12109, 10970, 11485, 12109, 1700},
+ {20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, 8982, 9105, 9976, 10970, 10431, 10431, 11090, 11940, 1610},
+ {9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, 9812, 8863, 9733, 10854, 11348, 10334, 11090, 11940, 3040},
+ {4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, 9300, 9168, 11485, 13988, 12479, 12109, 13988, 15725, 7804},
+ {4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, 9300, 8982, 10970, 13138, 12109, 11629, 13138, 14731, 6994}};
+
+RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG] = {0x7FBF61E2, 0x7EFE4B00, 0x7DBF01E8, 0x7C0544D0,
+ 0x79D636E9, 0x773846E0, 0x74330F61, 0x70CF3251};
+RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES] = {-32628, -31517, -29333, -26149, -22076, -17250, -11837, -6021, 0,
+ 6021, 11837, 17250, 22076, 26149, 29333, 31517, 32628};
+RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1] = {-32210, -30555, -27860, -24216, -19747, -14606, -8967, -3023,
+ 3023, 8967, 14606, 19747, 24216, 27860, 30555, 32210};
+
+RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG] = {{17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040},
+ {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}};
+RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG] = {{3, 9, 23, 54, 111, 190, 268, 366},
+ {14, 42, 100, 157, 181, 178, 167, 185}};
+RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG] = {{0, 3, 12, 35, 89, 200, 390, 658},
+ {0, 14, 56, 156, 313, 494, 672, 839}};
+RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES] = {
+ {20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, 5504, 5637, 6566, 6758, 8433, 11348, 15186, 20480, 20480},
+ {20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, 5254, 5485, 5598, 6076, 7608, 10742, 15186, 20480, 20480},
+ {20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, 4585, 4682, 5859, 7764, 12109, 20480, 20480, 20480, 20480},
+ {20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, 3779, 3658, 6335, 9656, 13988, 20480, 20480, 20480, 20480},
+ {20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, 3249, 3493, 8483, 13988, 17234, 20480, 20480, 20480, 20480},
+ {20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, 3040, 2953, 9105, 15725, 20480, 20480, 20480, 20480, 20480},
+ {20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, 3346, 3000, 12109, 20480, 20480, 20480, 20480, 20480,
+ 20480},
+ {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480,
+ 20480}};
+RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES] = {
+ {1, 5, 15, 31, 54, 86, 97, 120, 159, 152, 111, 104, 59, 22, 6, 1, 1},
+ {1, 1, 1, 1, 13, 43, 94, 139, 173, 160, 154, 131, 78, 27, 6, 1, 1},
+ {1, 1, 1, 1, 9, 43, 106, 199, 217, 210, 141, 74, 17, 1, 1, 1, 1},
+ {1, 1, 1, 1, 2, 11, 49, 204, 285, 297, 120, 39, 9, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 7, 42, 241, 341, 314, 58, 9, 3, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 13, 205, 366, 377, 47, 5, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 13, 281, 330, 371, 17, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 5, 297, 1, 682, 26, 2, 1, 1, 1, 1, 1}};
+RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES] = {
+ {0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023},
+ {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023},
+ {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023},
+ {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023},
+ {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023},
+ {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023},
+ {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023},
+ {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023}};
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_8000[64] = {
+ 0x4000, 0x435c, 0x46e5, 0x4a9e, 0x4e89, 0x52a9, 0x5700, 0x5b91, 0x6060, 0x656f, 0x6ac2, 0x705d, 0x7643,
+ 0x7c79, 0x4181, 0x44f1, 0x4890, 0x4c5f, 0x5061, 0x549a, 0x590b, 0x5db7, 0x62a3, 0x67d1, 0x6d44, 0x7301,
+ 0x790a, 0x7f65, 0x430b, 0x4690, 0x4a44, 0x4e2a, 0x5245, 0x5696, 0x5b22, 0x5feb, 0x64f4, 0x6a41, 0x6fd5,
+ 0x75b4, 0x7be2, 0x4131, 0x449e, 0x4838, 0x4c02, 0x5000, 0x5433, 0x589f, 0x5d46, 0x622c, 0x6753, 0x6cc0,
+ 0x7275, 0x7878, 0x7ecb, 0x42b9, 0x463a, 0x49ea, 0x4dcb, 0x51e1, 0x562d, 0x5ab4, 0x5f77, 0x647a};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_8000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05};
+#else
+#define lpc_warp_pre_emphasis_64_8000 NULL
+#define lpc_warp_pre_emphasis_64_e_8000 NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_16000[64] = {
+ 0x4000, 0x445a, 0x4900, 0x4df7, 0x5344, 0x58ed, 0x5efa, 0x656f, 0x6c55, 0x73b2, 0x7b91, 0x41fc, 0x4678,
+ 0x4b43, 0x5061, 0x55d9, 0x5baf, 0x61eb, 0x6894, 0x6fb0, 0x7748, 0x7f65, 0x4407, 0x48a8, 0x4d98, 0x52df,
+ 0x5882, 0x5e87, 0x64f4, 0x6bd1, 0x7326, 0x7afb, 0x41ac, 0x4623, 0x4ae8, 0x5000, 0x5571, 0x5b40, 0x6174,
+ 0x6815, 0x6f29, 0x76b8, 0x7ecb, 0x43b5, 0x4850, 0x4d3a, 0x527b, 0x5817, 0x5e14, 0x647a, 0x6b4f, 0x729b,
+ 0x7a66, 0x415c, 0x45ce, 0x4a8d, 0x4f9f, 0x5509, 0x5ad1, 0x60fe, 0x6797, 0x6ea2, 0x7628, 0x7e31};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_16000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06};
+#else
+#define lpc_warp_pre_emphasis_64_16000 NULL
+#define lpc_warp_pre_emphasis_64_e_16000 NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_24000[64] = {
+ 0x4000, 0x455c, 0x4b2a, 0x5176, 0x5848, 0x5fac, 0x67af, 0x705d, 0x79c5, 0x41fc, 0x4782, 0x4d7f, 0x53fc,
+ 0x5b04, 0x62a3, 0x6ae5, 0x73d9, 0x7d8c, 0x4407, 0x49b9, 0x4fe6, 0x5696, 0x5dd6, 0x65b2, 0x6e35, 0x7770,
+ 0x40b8, 0x4623, 0x4c02, 0x5260, 0x5945, 0x60bf, 0x68d8, 0x71a0, 0x7b23, 0x42b9, 0x4850, 0x4e5e, 0x54ed,
+ 0x5c0a, 0x63be, 0x6c18, 0x7525, 0x7ef4, 0x44cb, 0x4a8d, 0x50cb, 0x578f, 0x5ee4, 0x66d6, 0x6f72, 0x78c7,
+ 0x4172, 0x46ed, 0x4cdd, 0x534c, 0x5a46, 0x61d5, 0x6a06, 0x72e6, 0x7c85, 0x4379, 0x491f, 0x4f3f};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_24000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08};
+#else
+#define lpc_warp_pre_emphasis_64_24000 NULL
+#define lpc_warp_pre_emphasis_64_e_24000 NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_32000[64] = {
+ 0x4000, 0x4661, 0x4d65, 0x551d, 0x5d99, 0x66ed, 0x7130, 0x7c79, 0x4471, 0x4b43, 0x52c4, 0x5b04, 0x6417,
+ 0x6e11, 0x790a, 0x428e, 0x4930, 0x507c, 0x5882, 0x6154, 0x6b08, 0x75b4, 0x40b8, 0x472b, 0x4e44, 0x5611,
+ 0x5ea6, 0x6815, 0x7275, 0x7dde, 0x4535, 0x4c1b, 0x53b2, 0x5c0a, 0x6536, 0x6f4d, 0x7a66, 0x434d, 0x4a02,
+ 0x5163, 0x5980, 0x626c, 0x6c3c, 0x7706, 0x4172, 0x47f8, 0x4f25, 0x5708, 0x5fb5, 0x6940, 0x73be, 0x7f48,
+ 0x45fc, 0x4cf6, 0x54a2, 0x5d12, 0x6659, 0x708d, 0x7bc6, 0x440e, 0x4ad7, 0x524d, 0x5a81, 0x6387};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_32000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09};
+#else
+#define lpc_warp_pre_emphasis_64_32000 NULL
+#define lpc_warp_pre_emphasis_64_e_32000 NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_48000[64] = {
+ 0x4000, 0x476b, 0x4fb1, 0x58ed, 0x633c, 0x6ebc, 0x7b91, 0x44f1, 0x4cee, 0x55d9, 0x5fcb, 0x6ae5, 0x7748,
+ 0x428e, 0x4a44, 0x52df, 0x5c7a, 0x6731, 0x7326, 0x403f, 0x47b1, 0x5000, 0x5945, 0x639e, 0x6f29, 0x7c0b,
+ 0x4535, 0x4d3a, 0x562d, 0x602a, 0x6b4f, 0x77be, 0x42cf, 0x4a8d, 0x5331, 0x5cd5, 0x6797, 0x7398, 0x407f,
+ 0x47f8, 0x504f, 0x599d, 0x6400, 0x6f97, 0x7c85, 0x457a, 0x4d87, 0x5683, 0x6089, 0x6bb9, 0x7834, 0x4311,
+ 0x4ad7, 0x5383, 0x5d31, 0x67fd, 0x740a, 0x40be, 0x483f, 0x509e, 0x59f6, 0x6463, 0x7005, 0x7d00};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_48000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a};
+#else
+#define lpc_warp_pre_emphasis_64_48000 NULL
+#define lpc_warp_pre_emphasis_64_e_48000 NULL
+#endif
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_96000[64] = {
+ 0x4000, 0x4878, 0x520f, 0x5cea, 0x6936, 0x7721, 0x4372, 0x4c5f, 0x567a, 0x61eb, 0x6ee0, 0x7d8c, 0x4714,
+ 0x507c, 0x5b22, 0x6731, 0x74d8, 0x4227, 0x4ae8, 0x54d1, 0x600a, 0x6cc0, 0x7b23, 0x45b7, 0x4ef1, 0x5963,
+ 0x6536, 0x729b, 0x40e2, 0x4978, 0x5331, 0x5e33, 0x6aaa, 0x78c7, 0x4461, 0x4d6d, 0x57ac, 0x6346, 0x7068,
+ 0x7f48, 0x4810, 0x5199, 0x5c64, 0x689e, 0x7676, 0x4311, 0x4bf1, 0x55fd, 0x615e, 0x6e40, 0x7cd7, 0x46ae,
+ 0x5008, 0x5a9f, 0x669d, 0x7430, 0x41c8, 0x4a7c, 0x5457, 0x5f80, 0x6c23, 0x7a72, 0x4553, 0x4e7f};
+
+RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_96000[64] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c};
+#else
+# define lpc_warp_pre_emphasis_64_96000 NULL
+# define lpc_warp_pre_emphasis_64_e_96000 NULL
+#endif
+
+RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_8000,
+ lpc_warp_pre_emphasis_64_16000,
+ lpc_warp_pre_emphasis_64_24000,
+ lpc_warp_pre_emphasis_64_32000,
+ lpc_warp_pre_emphasis_64_48000,
+ lpc_warp_pre_emphasis_64_96000
+};
+
+RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_e_8000,
+ lpc_warp_pre_emphasis_64_e_16000,
+ lpc_warp_pre_emphasis_64_e_24000,
+ lpc_warp_pre_emphasis_64_e_32000,
+ lpc_warp_pre_emphasis_64_e_48000,
+ lpc_warp_pre_emphasis_64_e_96000
+};
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_8000[20] = {0x4be4, 0x5b79, 0x7a43, 0x53bf, 0x7106, 0x4a1f, 0x5e46,
+ 0x7477, 0x4613, 0x5260, 0x5ed4, 0x6b21, 0x76f9, 0x4109,
+ 0x4612, 0x4a79, 0x4e22, 0x50f6, 0x52e2, 0x53dc};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_e_8000[20] = {
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_8000[40] = {
+ 0x4a6c, 0x4e55, 0x5622, 0x61c5, 0x712d, 0x4220, 0x4d71, 0x5a77, 0x691e, 0x794e, 0x4577, 0x4ef1, 0x5906, 0x63a6,
+ 0x6ec1, 0x7a44, 0x430f, 0x491f, 0x4f46, 0x557c, 0x5bb8, 0x61ee, 0x6815, 0x6e25, 0x7412, 0x79d4, 0x7f61, 0x4259,
+ 0x44de, 0x473c, 0x4970, 0x4b76, 0x4d4b, 0x4eec, 0x5056, 0x5187, 0x527e, 0x5338, 0x53b5, 0x53f3};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_8000[40] = {
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_8000[80] = {
+ 0x4a0e, 0x4b09, 0x4cfd, 0x4fec, 0x53d2, 0x58af, 0x5e81, 0x6545, 0x6cf9, 0x759a, 0x7f25, 0x44ca, 0x4a73, 0x508a,
+ 0x570e, 0x5dfa, 0x654e, 0x6d06, 0x751e, 0x7d94, 0x4332, 0x47c6, 0x4c83, 0x5168, 0x5673, 0x5ba2, 0x60f2, 0x6662,
+ 0x6bf0, 0x7199, 0x775b, 0x7d34, 0x4191, 0x4490, 0x4798, 0x4aa7, 0x4dba, 0x50d3, 0x53ee, 0x570b, 0x5a29, 0x5d46,
+ 0x6061, 0x637a, 0x668e, 0x699c, 0x6ca4, 0x6fa3, 0x729a, 0x7587, 0x7868, 0x7b3c, 0x7e03, 0x405e, 0x41b2, 0x42fd,
+ 0x4440, 0x4579, 0x46a9, 0x47cd, 0x48e7, 0x49f6, 0x4af9, 0x4bf0, 0x4cdb, 0x4db8, 0x4e89, 0x4f4c, 0x5001, 0x50a8,
+ 0x5140, 0x51ca, 0x5246, 0x52b2, 0x530f, 0x535d, 0x539b, 0x53ca, 0x53e9, 0x53f9};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_8000[80] = {
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+#else
+#define lpc_lin_pre_emphasis_20_8000 NULL
+#define lpc_lin_pre_emphasis_20_e_8000 NULL
+#define lpc_lin_pre_emphasis_40_8000 NULL
+#define lpc_lin_pre_emphasis_40_e_8000 NULL
+#define lpc_lin_pre_emphasis_80_8000 NULL
+#define lpc_lin_pre_emphasis_80_e_8000 NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_16000[40] = {
+ 0x516b, 0x5a81, 0x6c9d, 0x43d2, 0x55b6, 0x6bdd, 0x4313, 0x5233, 0x6336, 0x7602, 0x453d, 0x503e, 0x5bf4, 0x684b,
+ 0x7530, 0x4148, 0x4829, 0x4f33, 0x5658, 0x5d8f, 0x64cc, 0x6c03, 0x7328, 0x7a32, 0x408a, 0x43e1, 0x471b, 0x4a31,
+ 0x4d1e, 0x4fde, 0x526d, 0x54c7, 0x56e7, 0x58cb, 0x5a70, 0x5bd2, 0x5cf0, 0x5dc9, 0x5e59, 0x5ea2};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_16000[40] = {
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_16000[80] = {
+ 0x5091, 0x52d7, 0x5762, 0x5e30, 0x673f, 0x728b, 0x4008, 0x47e3, 0x50d6, 0x5adb, 0x65ef, 0x720e, 0x7f33, 0x46ac,
+ 0x4e3c, 0x5647, 0x5ec9, 0x67bf, 0x7126, 0x7afa, 0x429b, 0x47ec, 0x4d6d, 0x531c, 0x58f7, 0x5efb, 0x6527, 0x6b78,
+ 0x71eb, 0x787d, 0x7f2d, 0x42fc, 0x466d, 0x49e8, 0x4d6d, 0x50fa, 0x548d, 0x5825, 0x5bc1, 0x5f5e, 0x62fd, 0x669a,
+ 0x6a36, 0x6dce, 0x7161, 0x74ee, 0x7872, 0x7bee, 0x7f5f, 0x4162, 0x430e, 0x44b3, 0x4650, 0x47e4, 0x496f, 0x4af0,
+ 0x4c67, 0x4dd2, 0x4f33, 0x5087, 0x51ce, 0x5309, 0x5436, 0x5554, 0x5665, 0x5766, 0x5858, 0x593a, 0x5a0d, 0x5acf,
+ 0x5b80, 0x5c20, 0x5caf, 0x5d2d, 0x5d99, 0x5df4, 0x5e3c, 0x5e72, 0x5e97, 0x5ea9};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_16000[80] = {
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+#else
+#define lpc_lin_pre_emphasis_40_16000 NULL
+#define lpc_lin_pre_emphasis_40_e_16000 NULL
+#define lpc_lin_pre_emphasis_80_16000 NULL
+#define lpc_lin_pre_emphasis_80_e_16000 NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_24000[40] = {
+ 0x44f2, 0x59a3, 0x4172, 0x603b, 0x447d, 0x5db8, 0x7ba7, 0x4f0d, 0x626d, 0x77d6, 0x4793, 0x541b, 0x6171, 0x6f7f,
+ 0x7e2f, 0x46b5, 0x4e8b, 0x568f, 0x5eb2, 0x66ea, 0x6f28, 0x775f, 0x7f83, 0x43c3, 0x47ae, 0x4b7d, 0x4f29, 0x52ac,
+ 0x5602, 0x5924, 0x5c0e, 0x5ebb, 0x6127, 0x634e, 0x652d, 0x66c1, 0x6807, 0x68fd, 0x69a2, 0x69f5};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_24000[40] = {
+ (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_24000[60] = {
+ 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222,
+ 0x5f0e, 0x6ce3, 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff,
+ 0x4d39, 0x5288, 0x57e8, 0x5d55, 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c,
+ 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e, 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27,
+ 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c, 0x691e, 0x698c, 0x69d6, 0x69fb};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_24000[60] = {
+ (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_24000[80] = {
+ 0x4301, 0x482e, 0x5287, 0x6208, 0x76a9, 0x4832, 0x5797, 0x697e, 0x7dde, 0x4a59, 0x56f7, 0x64c5, 0x73bd, 0x41ed,
+ 0x4a8a, 0x53b2, 0x5d63, 0x6798, 0x724d, 0x7d7e, 0x4493, 0x4aa1, 0x50e5, 0x575e, 0x5e0a, 0x64e4, 0x6beb, 0x731d,
+ 0x7a75, 0x40f9, 0x44c7, 0x48a5, 0x4c91, 0x5088, 0x548a, 0x5895, 0x5ca7, 0x60bf, 0x64db, 0x68f9, 0x6d18, 0x7136,
+ 0x7552, 0x796a, 0x7d7c, 0x40c4, 0x42c4, 0x44c0, 0x46b6, 0x48a5, 0x4a8c, 0x4c6b, 0x4e41, 0x500e, 0x51d0, 0x5386,
+ 0x5531, 0x56cf, 0x5860, 0x59e4, 0x5b59, 0x5cbf, 0x5e16, 0x5f5c, 0x6092, 0x61b7, 0x62cb, 0x63cd, 0x64bc, 0x6599,
+ 0x6663, 0x671a, 0x67bd, 0x684c, 0x68c7, 0x692e, 0x6980, 0x69be, 0x69e8, 0x69fd};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_24000[80] = {
+ (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+#else
+#define lpc_lin_pre_emphasis_60_24000 NULL
+#define lpc_lin_pre_emphasis_60_e_24000 NULL
+#define lpc_lin_pre_emphasis_40_24000 NULL
+#define lpc_lin_pre_emphasis_40_e_24000 NULL
+#define lpc_lin_pre_emphasis_80_24000 NULL
+#define lpc_lin_pre_emphasis_80_e_24000 NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_32000[80] = {
+ 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c,
+ 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51,
+ 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a,
+ 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0,
+ 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108,
+ 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_32000[80] = {
+ (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+#else
+#define lpc_lin_pre_emphasis_80_32000 NULL
+#define lpc_lin_pre_emphasis_80_e_32000 NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_48000[60] = {
+ 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b,
+ 0x62fa, 0x727f, 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc,
+ 0x54b9, 0x5aae, 0x60b6, 0x66cd, 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf,
+ 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f, 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc,
+ 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457, 0x74fb, 0x7576, 0x75c9, 0x75f2};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_48000[60] = {
+ (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_48000[80] = {
+ 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c,
+ 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51,
+ 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a,
+ 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0,
+ 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108,
+ 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_48000[80] = {
+ (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+#else
+#define lpc_lin_pre_emphasis_60_48000 NULL
+#define lpc_lin_pre_emphasis_60_e_48000 NULL
+#define lpc_lin_pre_emphasis_80_48000 NULL
+#define lpc_lin_pre_emphasis_80_e_48000 NULL
+#endif
+
+# if defined(SUBSET_SWB) || defined(SUBSET_FB)
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_0_92[80] = {
+ 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c,
+ 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51,
+ 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a,
+ 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0,
+ 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108,
+ 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_0_92[80] = {
+ (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+# else
+# define lpc_lin_pre_emphasis_80_0_92 NULL
+# define lpc_lin_pre_emphasis_80_e_0_92 NULL
+# endif
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ] = {lpc_lin_pre_emphasis_80_8000, lpc_lin_pre_emphasis_80_16000,
+ lpc_lin_pre_emphasis_80_24000, lpc_lin_pre_emphasis_80_32000,
+ lpc_lin_pre_emphasis_80_48000
+#ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_0_92
+#endif
+ };
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_80_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_80_e_24000,
+ lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000
+#ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_e_0_92
+#endif
+};
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_40_8000, lpc_lin_pre_emphasis_80_16000, lpc_lin_pre_emphasis_40_24000,
+ lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_80_48000
+#ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_0_92
+#endif
+};
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_40_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_40_e_24000,
+ lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000
+#ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_e_0_92
+#endif
+};
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_20_8000, lpc_lin_pre_emphasis_40_16000, lpc_lin_pre_emphasis_60_24000,
+ lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_60_48000
+#ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_0_92
+#endif
+};
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_20_e_8000, lpc_lin_pre_emphasis_40_e_16000, lpc_lin_pre_emphasis_60_e_24000,
+ lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_60_e_48000
+# ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_e_0_92
+#endif
+};
+
+# ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_62[60] = {
+ 0x4a26, 0x4be4, 0x4f5d, 0x5490, 0x5b79, 0x6414, 0x6e59, 0x7a43, 0x43e4, 0x4b6f, 0x53bf, 0x5ccc, 0x6690, 0x7106,
+ 0x7c25, 0x43f3, 0x4a1f, 0x5095, 0x574e, 0x5e46, 0x6578, 0x6cdf, 0x7477, 0x7c39, 0x4210, 0x4613, 0x4a24, 0x4e3e,
+ 0x5260, 0x5686, 0x5aae, 0x5ed4, 0x62f6, 0x6710, 0x6b21, 0x6f24, 0x7318, 0x76f9, 0x7ac4, 0x7e78, 0x4109, 0x42c7,
+ 0x4475, 0x4612, 0x479d, 0x4915, 0x4a79, 0x4bc8, 0x4d01, 0x4e22, 0x4f2c, 0x501e, 0x50f6, 0x51b4, 0x5259, 0x52e2,
+ 0x5351, 0x53a4, 0x53dc, 0x53f8};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_62[60] = {
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_72[60] = {
+ 0x50c9, 0x54d4, 0x5ce6, 0x68f9, 0x7906, 0x4681, 0x526e, 0x6043, 0x6ff6, 0x40be, 0x4a65, 0x54e8, 0x6040, 0x6c65,
+ 0x794f, 0x437a, 0x4aa6, 0x5226, 0x59f5, 0x620c, 0x6a68, 0x7301, 0x7bd2, 0x426a, 0x4701, 0x4baa, 0x5062, 0x5526,
+ 0x59f2, 0x5ec4, 0x6397, 0x6869, 0x6d35, 0x71f9, 0x76b1, 0x7b5a, 0x7ff1, 0x4239, 0x446d, 0x4694, 0x48aa, 0x4ab0,
+ 0x4ca4, 0x4e84, 0x504f, 0x5204, 0x53a1, 0x5526, 0x5691, 0x57e1, 0x5916, 0x5a2e, 0x5b29, 0x5c07, 0x5cc5, 0x5d65,
+ 0x5de6, 0x5e46, 0x5e87, 0x5ea7};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_72[60] = {
+ (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_82[60] = {
+ 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222, 0x5f0e, 0x6ce3,
+ 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff, 0x4d39, 0x5288, 0x57e8, 0x5d55,
+ 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c, 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e,
+ 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27, 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c,
+ 0x691e, 0x698c, 0x69d6, 0x69fb};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_82[60] = {
+ (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_92[60] = {
+ 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b, 0x62fa, 0x727f,
+ 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc, 0x54b9, 0x5aae, 0x60b6, 0x66cd,
+ 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf, 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f,
+ 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc, 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457,
+ 0x74fb, 0x7576, 0x75c9, 0x75f2};
+RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_92[60] = {
+ (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001,
+ (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002,
+ (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002};
+
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_60_0_62, lpc_lin_pre_emphasis_60_0_72, lpc_lin_pre_emphasis_60_0_82,
+ lpc_lin_pre_emphasis_80_0_92, lpc_lin_pre_emphasis_60_0_92
+# ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_0_92
+# endif
+ };
+RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ] = {
+ lpc_lin_pre_emphasis_60_e_0_62, lpc_lin_pre_emphasis_60_e_0_72, lpc_lin_pre_emphasis_60_e_0_82,
+ lpc_lin_pre_emphasis_80_e_0_92, lpc_lin_pre_emphasis_60_e_0_92
+# ifdef ENABLE_HR_MODE
+ , lpc_lin_pre_emphasis_80_e_0_92
+# endif
+ };
+# endif
+# endif
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_8000[16] = {0x4000, 0x673f, 0x5348, 0x432d, 0x6c5f, 0x576a,
+ 0x4682, 0x71bf, 0x5bc0, 0x4a02, 0x7764, 0x604d,
+ 0x4dae, 0x7d50, 0x6514, 0x5188};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_8000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc};
+#else
+#define lpc_warp_dee_emphasis_16_8000 NULL
+#define lpc_warp_dee_emphasis_16_e_8000 NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_16000[16] = {0x4000, 0x6119, 0x49a8, 0x6fc0, 0x54c5, 0x404e,
+ 0x618f, 0x4a02, 0x7048, 0x552c, 0x409c, 0x6206,
+ 0x4a5c, 0x70d0, 0x5594, 0x40eb};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_16000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff,
+ (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc,
+ (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffb};
+#else
+#define lpc_warp_dee_emphasis_16_16000 NULL
+#define lpc_warp_dee_emphasis_16_e_16000 NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_24000[16] = {0x4000, 0x5b51, 0x4125, 0x5cf3, 0x424f, 0x5e9c,
+ 0x437f, 0x604d, 0x44b4, 0x6206, 0x45ee, 0x63c7,
+ 0x472e, 0x658f, 0x4874, 0x6760};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_24000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe,
+ (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb,
+ (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9};
+#else
+#define lpc_warp_dee_emphasis_16_24000 NULL
+#define lpc_warp_dee_emphasis_16_e_24000 NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_32000[16] = {0x4000, 0x55e1, 0x733b, 0x4d50, 0x67bd, 0x4599,
+ 0x5d64, 0x7d50, 0x5413, 0x70d0, 0x4bb0, 0x658f,
+ 0x4423, 0x5b6e, 0x7aaf, 0x524f};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_32000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe,
+ (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa,
+ (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff8};
+#else
+#define lpc_warp_dee_emphasis_16_32000 NULL
+#define lpc_warp_dee_emphasis_16_e_32000 NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_48000[16] = {0x4000, 0x50c3, 0x65ea, 0x404e, 0x5126, 0x6666,
+ 0x409c, 0x5188, 0x66e3, 0x40eb, 0x51ec, 0x6760,
+ 0x413a, 0x524f, 0x67de, 0x4189};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_48000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd,
+ (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfff9,
+ (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff7, (Word16)0xfff7};
+#else
+#define lpc_warp_dee_emphasis_16_48000 NULL
+#define lpc_warp_dee_emphasis_16_e_48000 NULL
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_96000[16] = {0x4000, 0x4bf4, 0x5a23, 0x6af9, 0x7ef3, 0x4b54,
+ 0x5966, 0x6a18, 0x7de9, 0x4ab6, 0x58aa, 0x6939,
+ 0x7ce0, 0x4a19, 0x57f0, 0x685d};
+
+RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_96000[16] = {
+ (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd,
+ (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8,
+ (Word16)0xfff7, (Word16)0xfff7, (Word16)0xfff6, (Word16)0xfff5};
+# else
+# define lpc_warp_dee_emphasis_16_96000 NULL
+# define lpc_warp_dee_emphasis_16_e_96000 NULL
+# endif
+
+RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ] = {
+ lpc_warp_dee_emphasis_16_8000, lpc_warp_dee_emphasis_16_16000, lpc_warp_dee_emphasis_16_24000,
+ lpc_warp_dee_emphasis_16_32000, lpc_warp_dee_emphasis_16_48000, lpc_warp_dee_emphasis_16_96000};
+RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ] = {
+ lpc_warp_dee_emphasis_16_e_8000, lpc_warp_dee_emphasis_16_e_16000, lpc_warp_dee_emphasis_16_e_24000,
+ lpc_warp_dee_emphasis_16_e_32000, lpc_warp_dee_emphasis_16_e_48000, lpc_warp_dee_emphasis_16_e_96000};
+
+RAM_ALIGN const Word16 bands_nrg_scale[32] = {0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 bands_offset_48000_HR[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 25,
+ 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 72, 77, 83, 89, 95, 101, 108, 116,
+ 124, 133, 142, 152, 163, 174, 187, 200, 214, 229, 244, 262, 280, 299, 320, 343, 367, 392, 419, 449, 480};
+
+RAM_ALIGN const Word16 bands_offset_96000_HR[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 33, 36, 39, 42, 46, 50, 54, 59, 64, 69, 75, 82, 89, 96, 104, 113, 122, 132, 143, 155, 168, 181,
+ 196, 213, 230, 249, 270, 292, 316, 342, 371, 401, 434, 470, 509, 551, 596, 646, 699, 757, 819, 887, 960};
+
+RAM_ALIGN const Word16 *const bands_offset_HR[2] = {bands_offset_48000_HR, bands_offset_96000_HR};
+
+RAM_ALIGN const Word16 bands_offset_48000_5ms_HR[56] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 21, 23, 25, 27, 29, 31, 33, 35, 38, 41, 44, 47, 50, 54, 58, 62, 66, 71,
+ 76, 81, 87, 93, 100, 107, 114, 122, 131, 140, 149, 160, 171, 183, 196, 209, 224, 240};
+RAM_ALIGN const Word16 bands_offset_96000_5ms_HR[59] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21,
+ 23, 25, 27, 29, 31, 34, 37, 40, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 98, 106,
+ 115, 124, 135, 146, 158, 171, 185, 200, 217, 235, 254, 275, 298, 323, 349, 378, 409, 443, 480};
+
+RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2] = {bands_offset_48000_5ms_HR, bands_offset_96000_5ms_HR};
+
+RAM_ALIGN const Word16 bands_offset_48000_2_5ms_HR[46] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25,
+ 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 53, 57, 61, 65, 69, 74, 79, 85, 91, 97, 104, 112, 120};
+RAM_ALIGN const Word16 bands_offset_96000_2_5ms_HR[50] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32,
+ 35, 38, 41, 45, 49, 53, 57, 62, 67, 73, 79, 85, 92, 100, 108, 117, 127, 137, 149, 161, 174, 189, 204, 221, 240};
+
+RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2] = {bands_offset_48000_2_5ms_HR, bands_offset_96000_2_5ms_HR};
+
+#ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 bands_offset_48000_7_5ms_HR[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24,
+ 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 73, 78, 83, 89, 95, 101, 108,
+ 115, 122, 130, 139, 148, 158, 168, 179, 191, 203, 217, 231, 246, 262, 279, 298, 317, 338, 360};
+RAM_ALIGN const Word16 bands_offset_96000_7_5ms_HR[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28,
+ 30, 32, 35, 38, 41, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 97, 105, 114, 123, 132, 143, 155, 167,
+ 180, 195, 210, 227, 245, 265, 286, 309, 334, 360, 389, 420, 454, 490, 529, 572, 617, 667, 720};
+
+RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2] = {bands_offset_48000_7_5ms_HR, bands_offset_96000_7_5ms_HR};
+# endif
+#endif /* ENABLE_HR_MODE */
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 bands_offset_8000_lpc_warp[65] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019,
+ 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026,
+ 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0033, 0x0035,
+ 0x0037, 0x0039, 0x003b, 0x003d, 0x003f, 0x0041, 0x0043, 0x0045, 0x0047, 0x0049, 0x004b, 0x004d, 0x0050};
+#else
+#define bands_offset_8000_lpc_warp NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 bands_offset_16000_lpc_warp[65] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019,
+ 0x001a, 0x001b, 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030,
+ 0x0032, 0x0034, 0x0037, 0x003a, 0x003d, 0x0040, 0x0043, 0x0046, 0x0049, 0x004c, 0x0050, 0x0054, 0x0058,
+ 0x005c, 0x0060, 0x0065, 0x006a, 0x006f, 0x0074, 0x0079, 0x007f, 0x0085, 0x008b, 0x0092, 0x0099, 0x00a0};
+#else
+#define bands_offset_16000_lpc_warp NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 bands_offset_24000_lpc_warp[65] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0019, 0x001b,
+ 0x001d, 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003a,
+ 0x003d, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0055, 0x005a, 0x005f, 0x0064, 0x006a, 0x0070, 0x0076,
+ 0x007d, 0x0084, 0x008b, 0x0093, 0x009b, 0x00a4, 0x00ad, 0x00b7, 0x00c1, 0x00cc, 0x00d7, 0x00e3, 0x00f0};
+#else
+#define bands_offset_24000_lpc_warp NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 bands_offset_32000_lpc_warp[65] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e,
+ 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003c, 0x0040, 0x0044,
+ 0x0048, 0x004c, 0x0051, 0x0056, 0x005b, 0x0061, 0x0067, 0x006d, 0x0074, 0x007b, 0x0083, 0x008b, 0x0094,
+ 0x009d, 0x00a6, 0x00b0, 0x00bb, 0x00c7, 0x00d3, 0x00e0, 0x00ee, 0x00fc, 0x010c, 0x011c, 0x012e, 0x0140};
+#else
+#define bands_offset_32000_lpc_warp NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 bands_offset_48000_lpc_warp[65] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020,
+ 0x0022, 0x0024, 0x0027, 0x002a, 0x002d, 0x0030, 0x0033, 0x0037, 0x003b, 0x003f, 0x0043, 0x0047, 0x004c,
+ 0x0051, 0x0056, 0x005c, 0x0062, 0x0069, 0x0070, 0x0077, 0x007f, 0x0087, 0x0090, 0x009a, 0x00a4, 0x00af,
+ 0x00ba, 0x00c6, 0x00d3, 0x00e1, 0x00f0, 0x0100, 0x0111, 0x0123, 0x0136, 0x014a, 0x0160, 0x0177, 0x0190};
+#else
+#define bands_offset_48000_lpc_warp NULL
+#endif
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 bands_offset_8000_lpc_lin[81] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
+ 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029,
+ 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
+ 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050};
+#else
+#define bands_offset_8000_lpc_lin NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 bands_offset_16000_lpc_lin[81] = {
+ 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 0x0010, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a,
+ 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, 0x0032, 0x0034, 0x0036,
+ 0x0038, 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, 0x0052,
+ 0x0054, 0x0056, 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e,
+ 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007c, 0x007e, 0x0080, 0x0082, 0x0084, 0x0086, 0x0088, 0x008a,
+ 0x008c, 0x008e, 0x0090, 0x0092, 0x0094, 0x0096, 0x0098, 0x009a, 0x009c, 0x009e, 0x00a0};
+#else
+#define bands_offset_16000_lpc_lin NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 bands_offset_24000_lpc_lin[81] = {
+ 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, 0x0018, 0x001b, 0x001e, 0x0021, 0x0024, 0x0027,
+ 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004b, 0x004e, 0x0051,
+ 0x0054, 0x0057, 0x005a, 0x005d, 0x0060, 0x0063, 0x0066, 0x0069, 0x006c, 0x006f, 0x0072, 0x0075, 0x0078, 0x007b,
+ 0x007e, 0x0081, 0x0084, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, 0x0096, 0x0099, 0x009c, 0x009f, 0x00a2, 0x00a5,
+ 0x00a8, 0x00ab, 0x00ae, 0x00b1, 0x00b4, 0x00b7, 0x00ba, 0x00bd, 0x00c0, 0x00c3, 0x00c6, 0x00c9, 0x00cc, 0x00cf,
+ 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00de, 0x00e1, 0x00e4, 0x00e7, 0x00ea, 0x00ed, 0x00f0};
+#else
+#define bands_offset_24000_lpc_lin NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 bands_offset_32000_lpc_lin[81] = {
+ 0x0000, 0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018, 0x001c, 0x0020, 0x0024, 0x0028, 0x002c, 0x0030, 0x0034,
+ 0x0038, 0x003c, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0054, 0x0058, 0x005c, 0x0060, 0x0064, 0x0068, 0x006c,
+ 0x0070, 0x0074, 0x0078, 0x007c, 0x0080, 0x0084, 0x0088, 0x008c, 0x0090, 0x0094, 0x0098, 0x009c, 0x00a0, 0x00a4,
+ 0x00a8, 0x00ac, 0x00b0, 0x00b4, 0x00b8, 0x00bc, 0x00c0, 0x00c4, 0x00c8, 0x00cc, 0x00d0, 0x00d4, 0x00d8, 0x00dc,
+ 0x00e0, 0x00e4, 0x00e8, 0x00ec, 0x00f0, 0x00f4, 0x00f8, 0x00fc, 0x0100, 0x0104, 0x0108, 0x010c, 0x0110, 0x0114,
+ 0x0118, 0x011c, 0x0120, 0x0124, 0x0128, 0x012c, 0x0130, 0x0134, 0x0138, 0x013c, 0x0140};
+#else
+#define bands_offset_32000_lpc_lin NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 bands_offset_48000_lpc_lin[81] = {
+ 0x0000, 0x0006, 0x000c, 0x0012, 0x0018, 0x001e, 0x0024, 0x002a, 0x0030, 0x0036, 0x003c, 0x0042, 0x0048, 0x004e,
+ 0x0054, 0x005a, 0x0060, 0x0066, 0x006c, 0x0072, 0x0078, 0x007e, 0x0084, 0x008a, 0x0090, 0x0096, 0x009c, 0x00a2,
+ 0x00a8, 0x00ae, 0x00b4, 0x00ba, 0x00c0, 0x00c6, 0x00cc, 0x00d2, 0x00d8, 0x00de, 0x00e4, 0x00ea, 0x00f0, 0x00f6,
+ 0x00fc, 0x0102, 0x0108, 0x010e, 0x0114, 0x011a, 0x0120, 0x0126, 0x012c, 0x0132, 0x0138, 0x013e, 0x0144, 0x014a,
+ 0x0150, 0x0156, 0x015c, 0x0162, 0x0168, 0x016e, 0x0174, 0x017a, 0x0180, 0x0186, 0x018c, 0x0192, 0x0198, 0x019e,
+ 0x01a4, 0x01aa, 0x01b0, 0x01b6, 0x01bc, 0x01c2, 0x01c8, 0x01ce, 0x01d4, 0x01da, 0x01e0};
+#else
+#define bands_offset_48000_lpc_lin NULL
+#endif
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_5ms[40] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
+ 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0028};
+#else
+#define bands_offset_8000_lpc_warp_5ms NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_5ms[51] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c,
+ 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019,
+ 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e,
+ 0x0030, 0x0032, 0x0034, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004c, 0x0050};
+#else
+#define bands_offset_16000_lpc_warp_5ms NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_5ms[53] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x001a, 0x001c, 0x001e,
+ 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041,
+ 0x0045, 0x0049, 0x004d, 0x0051, 0x0056, 0x005b, 0x0060, 0x0065, 0x006b, 0x0071, 0x0078};
+#else
+#define bands_offset_24000_lpc_warp_5ms NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_5ms[55] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020,
+ 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003d, 0x0041, 0x0045, 0x0049,
+ 0x004e, 0x0053, 0x0058, 0x005d, 0x0063, 0x0069, 0x0070, 0x0077, 0x007e, 0x0086, 0x008e, 0x0097, 0x00a0};
+#else
+#define bands_offset_32000_lpc_warp_5ms NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_5ms[56] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d,
+ 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0017, 0x0019, 0x001b, 0x001d, 0x001f, 0x0021,
+ 0x0023, 0x0025, 0x0028, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003b, 0x003f, 0x0043, 0x0048, 0x004d, 0x0052,
+ 0x0057, 0x005d, 0x0063, 0x0069, 0x0070, 0x0078, 0x0080, 0x0088, 0x0091, 0x009b, 0x00a5, 0x00b0, 0x00bb, 0x00c8};
+#else
+#define bands_offset_48000_lpc_warp_5ms NULL
+#endif
+
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
+#else
+#define bands_offset_8000_lpc_warp_2_5ms NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_2_5ms[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40};
+#else
+#define bands_offset_16000_lpc_warp_2_5ms NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28,
+ 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 60};
+#else
+#define bands_offset_24000_lpc_warp_2_5ms NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_2_5ms[44] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80};
+#else
+#define bands_offset_32000_lpc_warp_2_5ms NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_2_5ms[45] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23,
+ 25, 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 52, 56, 60, 64, 68, 72, 77, 82, 87, 93, 100};
+#else
+#define bands_offset_48000_lpc_warp_2_5ms NULL
+#endif
+
+
+
+RAM_ALIGN const Word16 *const bands_offset[6] = {bands_offset_8000_lpc_warp, bands_offset_16000_lpc_warp,
+ bands_offset_24000_lpc_warp, bands_offset_32000_lpc_warp,
+ bands_offset_48000_lpc_warp, NULL};
+
+#ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS] = {60, 34, 27, 24, 22
+# ifdef ENABLE_HR_MODE
+ , 20, 16
+# endif
+};
+RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS] = {0, 48, 38, 33, 31
+# ifdef ENABLE_HR_MODE
+ , 29, 24
+# endif
+};
+# endif
+
+RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS] = {49, 28, 23, 20, 18
+# ifdef ENABLE_HR_MODE
+ , 17, 12
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS] = {63, 40, 33, 29, 27
+# ifdef ENABLE_HR_MODE
+ , 25, 21
+# endif
+ };
+
+RAM_ALIGN const Word16 *const bands_offset_5ms[6] = {bands_offset_8000_lpc_warp_5ms, bands_offset_16000_lpc_warp_5ms,
+ bands_offset_24000_lpc_warp_5ms, bands_offset_32000_lpc_warp_5ms,
+ bands_offset_48000_lpc_warp_5ms, NULL};
+RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS] = {38, 30, 24, 22, 21
+# ifdef ENABLE_HR_MODE
+ , 19, 17
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS] = {39, 42, 34, 32, 29
+# ifdef ENABLE_HR_MODE
+ , 27, 24
+# endif
+ };
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64, 64};
+# else
+RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64};
+# endif
+#endif
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55, 58};
+#else
+RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55};
+#endif
+
+RAM_ALIGN const Word16 *const bands_offset_2_5ms[6] = {
+ bands_offset_8000_lpc_warp_2_5ms, bands_offset_16000_lpc_warp_2_5ms, bands_offset_24000_lpc_warp_2_5ms,
+ bands_offset_32000_lpc_warp_2_5ms, bands_offset_48000_lpc_warp_2_5ms, NULL};
+
+RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS] = {20, 30, 26, 24, 21
+# ifdef ENABLE_HR_MODE
+ , 19, 16
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS] = {20, 35, 35, 32, 29
+# ifdef ENABLE_HR_MODE
+ , 28, 24
+# endif
+ };
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 bands_number_2_5ms_HR[] = {20, 35, 40, 43, 45, 49};
+RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44, 49};
+# else
+RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44};
+# endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 bands_offset_96000_lpc_lin[81] =
+{
+ 0x0000, 0x000c, 0x0018, 0x0024, 0x0030, 0x003c, 0x0048, 0x0054, 0x0060, 0x006c, 0x0078, 0x0084, 0x0090, 0x009c,
+ 0x00a8, 0x00b4, 0x00c0, 0x00cc, 0x00d8, 0x00e4, 0x00f0, 0x00fc, 0x0108, 0x0114, 0x0120, 0x012c, 0x0138, 0x0144,
+ 0x0150, 0x015c, 0x0168, 0x0174, 0x0180, 0x018c, 0x0198, 0x01a4, 0x01b0, 0x01bc, 0x01c8, 0x01d4, 0x01e0, 0x01ec,
+ 0x01f8, 0x0204, 0x0210, 0x021c, 0x0228, 0x0234, 0x0240, 0x024c, 0x0258, 0x0264, 0x0270, 0x027c, 0x0288, 0x0294,
+ 0x02a0, 0x02ac, 0x02b8, 0x02c4, 0x02d0, 0x02dc, 0x02e8, 0x02f4, 0x0300, 0x030c, 0x0318, 0x0324, 0x0330, 0x033c,
+ 0x0348, 0x0354, 0x0360, 0x036c, 0x0378, 0x0384, 0x0390, 0x039c, 0x03a8, 0x03b4, 0x03c0
+};
+
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 bands_offset_96000_lpc_lin_7_5ms[81] =
+{
+ 0x0000, 0x0009, 0x0012, 0x001b, 0x0024, 0x002d, 0x0036, 0x003f, 0x0048, 0x0051, 0x005a, 0x0063, 0x006c, 0x0075,
+ 0x007e, 0x0087, 0x0090, 0x0099, 0x00a2, 0x00ab, 0x00b4, 0x00bd, 0x00c6, 0x00cf, 0x00d8, 0x00e1, 0x00ea, 0x00f3,
+ 0x00fc, 0x0105, 0x010e, 0x0117, 0x0120, 0x0129, 0x0132, 0x013b, 0x0144, 0x014d, 0x0156, 0x015f, 0x0168, 0x0171,
+ 0x017a, 0x0183, 0x018c, 0x0195, 0x019e, 0x01a7, 0x01b0, 0x01b9, 0x01c2, 0x01cb, 0x01d4, 0x01dd, 0x01e6, 0x01ef,
+ 0x01f8, 0x0201, 0x020a, 0x0213, 0x021c, 0x0225, 0x022e, 0x0237, 0x0240, 0x0249, 0x0252, 0x025b, 0x0264, 0x026d,
+ 0x0276, 0x027f, 0x0288, 0x0291, 0x029a, 0x02a3, 0x02ac, 0x02b5, 0x02be, 0x02c7, 0x02d0
+};
+# endif
+# endif
+
+
+RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin,
+ bands_offset_24000_lpc_lin, bands_offset_32000_lpc_lin,
+ bands_offset_48000_lpc_lin
+# ifdef ENABLE_HR_MODE
+ , bands_offset_96000_lpc_lin
+# endif
+ };
+
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin,
+ bands_offset_24000_lpc_lin, bands_offset_24000_lpc_lin,
+ bands_offset_48000_lpc_lin
+# ifdef ENABLE_HR_MODE
+ , bands_offset_96000_lpc_lin_7_5ms
+# endif
+ };
+# endif
+
+RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin,
+ bands_offset_24000_lpc_lin, bands_offset_16000_lpc_lin,
+ bands_offset_24000_lpc_lin
+# ifdef ENABLE_HR_MODE
+ , bands_offset_48000_lpc_lin
+# endif
+ };
+RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin,
+ bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin,
+ bands_offset_16000_lpc_lin
+# ifdef ENABLE_HR_MODE
+ , bands_offset_24000_lpc_lin
+# endif
+ };
+
+RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ] = {80, 0, 0, 0, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ] = {0, 80, 0, 0, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+
+# ifdef CR8_G_ADD_75MS
+RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ] = {60, 0, 0, 0, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+
+RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ] = {0, 60, 0, 0, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+#endif
+
+RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ] = {40, 80, 0, 0, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 80, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ] = {20, 40, 60, 80, 0
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 0, 60
+# ifdef ENABLE_HR_MODE
+ , 0
+# endif
+ };
+#ifdef CR8_G_ADD_75MS
+# ifdef SUBSET_NB
+RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_7_5ms[61] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60};
+# else
+# define bands_offset_8000_lpc_warp_7_5ms NULL
+# endif
+
+# ifdef SUBSET_WB
+RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_7_5ms[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52,
+ 54, 56, 58, 60, 62, 65, 68, 71, 74, 77, 80, 83, 86, 90, 94, 98, 102, 106, 110, 115, 120};
+# else
+# define bands_offset_16000_lpc_warp_7_5ms NULL
+# endif
+
+# ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_7_5ms[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 52, 55, 58, 61, 64,
+ 67, 70, 74, 78, 82, 86, 90, 95, 100, 105, 110, 115, 121, 127, 134, 141, 148, 155, 163, 171, 180};
+# else
+# define bands_offset_24000_lpc_warp_7_5ms NULL
+# endif
+
+# ifdef SUBSET_SWB
+RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_7_5ms[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 45, 48, 51, 54, 57, 60, 63, 67, 71, 75,
+ 79, 84, 89, 94, 99, 105, 111, 117, 124, 131, 138, 146, 154, 163, 172, 182, 192, 203, 215, 227, 240};
+# else
+# define bands_offset_32000_lpc_warp_7_5ms NULL
+# endif
+
+# ifdef SUBSET_FB
+RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_7_5ms[65] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80, 85,
+ 90, 96, 102, 108, 115, 122, 129, 137, 146, 155, 165, 175, 186, 197, 209, 222, 236, 251, 266, 283, 300};
+# else
+# define bands_offset_48000_lpc_warp_7_5ms NULL
+# endif
+
+RAM_ALIGN const Word16 *const bands_offset_7_5ms[5] = {
+ bands_offset_8000_lpc_warp_7_5ms, bands_offset_16000_lpc_warp_7_5ms, bands_offset_24000_lpc_warp_7_5ms,
+ bands_offset_32000_lpc_warp_7_5ms, bands_offset_48000_lpc_warp_7_5ms};
+# endif /* ifdef CR8_G_ADD_75MS */
+
+RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M] = {
+ 0x7ff9af04, 0x7fe6bcb0, 0x7fc72ae2, 0x7f9afcb9, 0x7f62368f, 0x7f1cde01, 0x7ecaf9e5, 0x7e6c9251,
+ 0x7e01b096, 0x7d8a5f40, 0x7d06aa16, 0x7c769e18, 0x7bda497d, 0x7b31bbb2, 0x7a7d055b, 0x79bc384d};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M] = {
+ 0x02835b5a, 0x05067734, 0x07891418, 0x0a0af299, 0x0c8bd35e, 0x0f0b7727, 0x11899ed3, 0x14060b68,
+ 0x16807e15, 0x18f8b83c, 0x1b6e7b7a, 0x1de189a6, 0x2051a4dd, 0x22be8f87, 0x25280c5e, 0x278dde6e};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_60_re[16] = {
+ 0x7ff4c56f, 0x7fd317b4, 0x7f9afcb9, 0x7f4c7e54, 0x7ee7aa4c, 0x7e6c9251, 0x7ddb4bfc, 0x7d33f0ca,
+ 0x7c769e18, 0x7ba3751d, 0x7aba9ae6, 0x79bc384d, 0x78a879f4, 0x777f903c, 0x7641af3d, 0x74ef0ebc};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_60_im[16] = {
+ 0x0359c428, 0x06b2f1d2, 0x0a0af299, 0x0d61304e, 0x10b5150f, 0x14060b68, 0x17537e63, 0x1a9cd9ac,
+ 0x1de189a6, 0x2120fb83, 0x245a9d65, 0x278dde6e, 0x2aba2ee4, 0x2ddf0040, 0x30fbc54d, 0x340ff242};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_40_re[16] = {
+ 0x7fe6bcb0, 0x7f9afcb9, 0x7f1cde01, 0x7e6c9251, 0x7d8a5f40, 0x7c769e18, 0x7b31bbb2, 0x79bc384d,
+ 0x7816a759, 0x7641af3d, 0x743e0918, 0x720c8075, 0x6fadf2fc, 0x6d23501b, 0x6a6d98a4, 0x678dde6e};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_40_im[16] = {
+ 0x05067734, 0x0a0af299, 0x0f0b7727, 0x14060b68, 0x18f8b83c, 0x1de189a6, 0x22be8f87, 0x278dde6e,
+ 0x2c4d9050, 0x30fbc54d, 0x3596a46c, 0x3a1c5c57, 0x3e8b240e, 0x42e13ba4, 0x471cece7, 0x4b3c8c12};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_20_re[16] = {
+ 0x7f9afcb9, 0x7e6c9251, 0x7c769e18, 0x79bc384d, 0x7641af3d, 0x720c8075, 0x6d23501b, 0x678dde6e,
+ 0x6154fb91, 0x5a82799a, 0x53211d18, 0x4b3c8c12, 0x42e13ba4, 0x3a1c5c57, 0x30fbc54d, 0x278dde6e};
+
+RAM_ALIGN const Word32 inv_odft_twiddle_20_im[16] = {
+ 0x0a0af299, 0x14060b68, 0x1de189a6, 0x278dde6e, 0x30fbc54d, 0x3a1c5c57, 0x42e13ba4, 0x4b3c8c12,
+ 0x53211d18, 0x5a82799a, 0x6154fb91, 0x678dde6e, 0x6d23501b, 0x720c8075, 0x7641af3d, 0x79bc384d};
+
+#ifdef SUBSET_NB
+RAM_ALIGN const Word16 resamp_filt_8k[240] = {
+ 214, 417, -1052, -4529, 26233, -4529, -1052, 417, 214, 0, 212, 277, -1281, -3928, 26037, -4979,
+ -755, 550, 206, -8, 200, 136, -1439, -3214, 25456, -5243, -401, 668, 187, -18, 180, 0,
+ -1522, -2427, 24506, -5289, 0, 763, 156, -28, 154, -125, -1534, -1605, 23211, -5090, 432, 831,
+ 114, -39, 124, -234, -1478, -785, 21609, -4626, 877, 865, 61, -50, 92, -323, -1361, 0,
+ 19741, -3885, 1317, 861, 0, -61, 60, -391, -1194, 720, 17658, -2863, 1729, 815, -68, -69,
+ 29, -436, -987, 1351, 15414, -1563, 2093, 727, -140, -76, 0, -457, -752, 1873, 13068, 0,
+ 2389, 598, -213, -79, -25, -457, -501, 2274, 10677, 1803, 2597, 430, -282, -77, -46, -436,
+ -247, 2545, 8302, 3815, 2700, 229, -345, -72, -61, -398, 0, 2686, 5997, 5997, 2686, 0,
+ -398, -61, -72, -345, 229, 2700, 3815, 8302, 2545, -247, -436, -46, -77, -282, 430, 2597,
+ 1803, 10677, 2274, -501, -457, -25, -79, -213, 598, 2389, 0, 13068, 1873, -752, -457, 0,
+ -76, -140, 727, 2093, -1563, 15414, 1351, -987, -436, 29, -69, -68, 815, 1729, -2863, 17658,
+ 720, -1194, -391, 60, -61, 0, 861, 1317, -3885, 19741, 0, -1361, -323, 92, -50, 61,
+ 865, 877, -4626, 21609, -785, -1478, -234, 124, -39, 114, 831, 432, -5090, 23211, -1605, -1534,
+ -125, 154, -28, 156, 763, 0, -5289, 24506, -2427, -1522, 0, 180, -18, 187, 668, -401,
+ -5243, 25456, -3214, -1439, 136, 200, -8, 206, 550, -755, -4979, 26037, -3928, -1281, 277, 212};
+#else
+#define resamp_filt_8k NULL
+#endif
+
+#ifdef SUBSET_WB
+RAM_ALIGN const Word16 resamp_filt_16k[240] = {
+ -61, 214, -398, 417, 0, -1052, 2686, -4529, 5997, 26233, 5997, -4529, 2686, -1052, 0, 417,
+ -398, 214, -61, 0, -72, 212, -345, 277, 229, -1281, 2700, -3928, 3815, 26037, 8302, -4979,
+ 2545, -755, -247, 550, -436, 206, -46, -8, -77, 200, -282, 136, 430, -1439, 2597, -3214,
+ 1803, 25456, 10677, -5243, 2274, -401, -501, 668, -457, 187, -25, -18, -79, 180, -213, 0,
+ 598, -1522, 2389, -2427, 0, 24506, 13068, -5289, 1873, 0, -752, 763, -457, 156, 0, -28,
+ -76, 154, -140, -125, 727, -1534, 2093, -1605, -1563, 23211, 15414, -5090, 1351, 432, -987, 831,
+ -436, 114, 29, -39, -69, 124, -68, -234, 815, -1478, 1729, -785, -2863, 21609, 17658, -4626,
+ 720, 877, -1194, 865, -391, 61, 60, -50, -61, 92, 0, -323, 861, -1361, 1317, 0,
+ -3885, 19741, 19741, -3885, 0, 1317, -1361, 861, -323, 0, 92, -61, -50, 60, 61, -391,
+ 865, -1194, 877, 720, -4626, 17658, 21609, -2863, -785, 1729, -1478, 815, -234, -68, 124, -69,
+ -39, 29, 114, -436, 831, -987, 432, 1351, -5090, 15414, 23211, -1563, -1605, 2093, -1534, 727,
+ -125, -140, 154, -76, -28, 0, 156, -457, 763, -752, 0, 1873, -5289, 13068, 24506, 0,
+ -2427, 2389, -1522, 598, 0, -213, 180, -79, -18, -25, 187, -457, 668, -501, -401, 2274,
+ -5243, 10677, 25456, 1803, -3214, 2597, -1439, 430, 136, -282, 200, -77, -8, -46, 206, -436,
+ 550, -247, -755, 2545, -4979, 8302, 26037, 3815, -3928, 2700, -1281, 229, 277, -345, 212, -72};
+#else
+#define resamp_filt_16k NULL
+#endif
+
+#ifdef SUBSET_SSWB
+RAM_ALIGN const Word16 resamp_filt_24k[240] = {
+ -50, 19, 143, -93, -290, 278, 485, -658, -701, 1396, 901, -3019, -1042, 10276, 17488, 10276,
+ -1042, -3019, 901, 1396, -701, -658, 485, 278, -290, -93, 143, 19, -50, 0, -46, 0,
+ 141, -45, -305, 185, 543, -501, -854, 1153, 1249, -2619, -1908, 8712, 17358, 11772, 0, -3319,
+ 480, 1593, -504, -796, 399, 367, -261, -142, 138, 40, -52, -5, -41, -17, 133, 0,
+ -304, 91, 574, -334, -959, 878, 1516, -2143, -2590, 7118, 16971, 13161, 1202, -3495, 0, 1731,
+ -267, -908, 287, 445, -215, -188, 125, 62, -52, -12, -34, -30, 120, 41, -291, 0,
+ 577, -164, -1015, 585, 1697, -1618, -3084, 5534, 16337, 14406, 2544, -3526, -523, 1800, 0, -985,
+ 152, 509, -156, -230, 104, 83, -48, -19, -26, -41, 103, 76, -265, -83, 554, 0,
+ -1023, 288, 1791, -1070, -3393, 3998, 15474, 15474, 3998, -3393, -1070, 1791, 288, -1023, 0, 554,
+ -83, -265, 76, 103, -41, -26, -19, -48, 83, 104, -230, -156, 509, 152, -985, 0,
+ 1800, -523, -3526, 2544, 14406, 16337, 5534, -3084, -1618, 1697, 585, -1015, -164, 577, 0, -291,
+ 41, 120, -30, -34, -12, -52, 62, 125, -188, -215, 445, 287, -908, -267, 1731, 0,
+ -3495, 1202, 13161, 16971, 7118, -2590, -2143, 1516, 878, -959, -334, 574, 91, -304, 0, 133,
+ -17, -41, -5, -52, 40, 138, -142, -261, 367, 399, -796, -504, 1593, 480, -3319, 0,
+ 11772, 17358, 8712, -1908, -2619, 1249, 1153, -854, -501, 543, 185, -305, -45, 141, 0, -46};
+#else
+#define resamp_filt_24k NULL
+#endif
+
+#ifdef SUBSET_SWB
+RAM_ALIGN const Word16 resamp_filt_32k[240] = {
+ -30, -31, 46, 107, 0, -199, -162, 209, 430, 0, -681, -526, 658, 1343, 0, -2264,
+ -1943, 2999, 9871, 13116, 9871, 2999, -1943, -2264, 0, 1343, 658, -526, -681, 0, 430, 209,
+ -162, -199, 0, 107, 46, -31, -30, 0, -25, -36, 30, 106, 31, -173, -195, 139,
+ 432, 114, -597, -641, 439, 1350, 360, -1964, -2313, 1908, 8829, 13019, 10804, 4151, -1431, -2489,
+ -393, 1273, 864, -378, -739, -123, 408, 275, -117, -218, -34, 103, 62, -23, -35, -4,
+ -20, -39, 14, 100, 57, -141, -218, 68, 416, 215, -494, -719, 216, 1298, 676, -1607,
+ -2545, 902, 7707, 12728, 11606, 5339, -781, -2621, -803, 1137, 1047, -200, -767, -251, 364, 334,
+ -62, -228, -70, 94, 77, -13, -38, -9, -14, -39, 0, 90, 78, -106, -229, 0,
+ 382, 299, -376, -761, 0, 1194, 937, -1214, -2644, 0, 6534, 12253, 12253, 6534, 0, -2644,
+ -1214, 937, 1194, 0, -761, -376, 299, 382, 0, -229, -106, 78, 90, 0, -39, -14,
+ -9, -38, -13, 77, 94, -70, -228, -62, 334, 364, -251, -767, -200, 1047, 1137, -803,
+ -2621, -781, 5339, 11606, 12728, 7707, 902, -2545, -1607, 676, 1298, 216, -719, -494, 215, 416,
+ 68, -218, -141, 57, 100, 14, -39, -20, -4, -35, -23, 62, 103, -34, -218, -117,
+ 275, 408, -123, -739, -378, 864, 1273, -393, -2489, -1431, 4151, 10804, 13019, 8829, 1908, -2313,
+ -1964, 360, 1350, 439, -641, -597, 114, 432, 139, -195, -173, 31, 106, 30, -36, -25};
+#else
+#define resamp_filt_32k NULL
+#endif
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 resamp_filt_96k[240] = {
+ -3, -7, -10, -13, -13, -10, -4, 5, 15, 26, 33, 36, 31, 19, 0, -23, -47, -66, -76,
+ -73, -54, -21, 23, 70, 111, 139, 143, 121, 72, 0, -84, -165, -227, -256, -240, -175, -67, 72,
+ 219, 349, 433, 448, 379, 225, 0, -268, -536, -755, -874, -848, -648, -260, 301, 1000, 1780, 2569, 3290,
+ 3869, 4243, 4372, 4243, 3869, 3290, 2569, 1780, 1000, 301, -260, -648, -848, -874, -755, -536, -268, 0, 225,
+ 379, 448, 433, 349, 219, 72, -67, -175, -240, -256, -227, -165, -84, 0, 72, 121, 143, 139, 111,
+ 70, 23, -21, -54, -73, -76, -66, -47, -23, 0, 19, 31, 36, 33, 26, 15, 5, -4, -10,
+ -13, -13, -10, -7, -3, 0, -1, -5, -8, -12, -13, -12, -8, 0, 10, 21, 30, 35, 34,
+ 26, 10, -11, -35, -58, -73, -76, -65, -39, 0, 46, 92, 127, 144, 136, 100, 38, -41, -125,
+ -199, -246, -254, -214, -126, 0, 146, 288, 398, 450, 424, 312, 120, -131, -405, -655, -830, -881, -771,
+ -477, 0, 636, 1384, 2178, 2943, 3601, 4084, 4340, 4340, 4084, 3601, 2943, 2178, 1384, 636, 0, -477, -771,
+ -881, -830, -655, -405, -131, 120, 312, 424, 450, 398, 288, 146, 0, -126, -214, -254, -246, -199, -125,
+ -41, 38, 100, 136, 144, 127, 92, 46, 0, -39, -65, -76, -73, -58, -35, -11, 10, 26, 34,
+ 35, 30, 21, 10, 0, -8, -12, -13, -12, -8, -5, -1};
+#else
+# define resamp_filt_96k NULL
+#endif
+
+#ifdef SUBSET_FB
+RAM_ALIGN const Word16 resamp_filt_48k[240] = {
+ -13, -25, -20, 10, 51, 71, 38, -47, -133, -145, -42, 139, 277, 242, 0, -329,
+ -511, -351, 144, 698, 895, 450, -535, -1510, -1697, -521, 1999, 5138, 7737, 8744, 7737, 5138,
+ 1999, -521, -1697, -1510, -535, 450, 895, 698, 144, -351, -511, -329, 0, 242, 277, 139,
+ -42, -145, -133, -47, 38, 71, 51, 10, -20, -25, -13, 0, -9, -23, -24, 0,
+ 41, 71, 52, -23, -115, -152, -78, 92, 254, 272, 76, -251, -493, -427, 0, 576,
+ 900, 624, -262, -1309, -1763, -954, 1272, 4356, 7203, 8679, 8169, 5886, 2767, 0, -1542, -1660,
+ -809, 240, 848, 796, 292, -252, -507, -398, -82, 199, 288, 183, 0, -130, -145, -71,
+ 20, 69, 60, 20, -15, -26, -17, -3, -6, -20, -26, -8, 31, 67, 62, 0,
+ -94, -152, -108, 45, 223, 287, 143, -167, -454, -480, -134, 439, 866, 758, 0, -1071,
+ -1748, -1295, 601, 3559, 6580, 8485, 8485, 6580, 3559, 601, -1295, -1748, -1071, 0, 758, 866,
+ 439, -134, -480, -454, -167, 143, 287, 223, 45, -108, -152, -94, 0, 62, 67, 31,
+ -8, -26, -20, -6, -3, -17, -26, -15, 20, 60, 69, 20, -71, -145, -130, 0,
+ 183, 288, 199, -82, -398, -507, -252, 292, 796, 848, 240, -809, -1660, -1542, 0, 2767,
+ 5886, 8169, 8679, 7203, 4356, 1272, -954, -1763, -1309, -262, 624, 900, 576, 0, -427, -493,
+ -251, 76, 272, 254, 92, -78, -152, -115, -23, 52, 71, 41, 0, -24, -23, -9};
+#else
+#define resamp_filt_48k NULL
+#endif
+
+
+RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ] = {resamp_filt_8k,
+ resamp_filt_16k,
+ resamp_filt_24k,
+ resamp_filt_32k,
+ resamp_filt_48k,
+ resamp_filt_96k
+};
+
+RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4] = {
+#ifdef SUBSET_NB
+ {24, 5, 0, 15},
+#else
+ {0},
+#endif
+#ifdef SUBSET_WB
+ {12, 10, 1, 3},
+#else
+ {0},
+#endif
+#ifdef SUBSET_SSWB
+ {8, 15, 1, 7},
+#else
+ {0},
+#endif
+#ifdef SUBSET_SWB
+ {6, 20, 2, 3},
+#else
+ {0},
+#endif
+#ifdef SUBSET_FB
+ {4, 30, 3, 3},
+#else
+ {0},
+#endif
+#ifdef ENABLE_HR_MODE
+ {2, 60, 7, 1},
+#endif
+};
+
+RAM_ALIGN const Word16 highpass50_filt_num[3] = {32204, -32204, 32204};
+RAM_ALIGN const Word16 highpass50_filt_den[2] = {32199, -31650};
+
+RAM_ALIGN const Word16 olpa_ac_weighting[98] = {
+ 32767, 32598, 32429, 32260, 32091, 31922, 31754, 31585, 31416, 31247, 31078, 30909, 30740, 30571,
+ 30402, 30233, 30065, 29896, 29727, 29558, 29389, 29220, 29051, 28882, 28713, 28544, 28376, 28207,
+ 28038, 27869, 27700, 27531, 27362, 27193, 27024, 26855, 26687, 26518, 26349, 26180, 26011, 25842,
+ 25673, 25504, 25335, 25166, 24998, 24829, 24660, 24491, 24322, 24153, 23984, 23815, 23646, 23477,
+ 23308, 23140, 22971, 22802, 22633, 22464, 22295, 22126, 21957, 21788, 21619, 21451, 21282, 21113,
+ 20944, 20775, 20606, 20437, 20268, 20099, 19930, 19762, 19593, 19424, 19255, 19086, 18917, 18748,
+ 18579, 18410, 18241, 18073, 17904, 17735, 17566, 17397, 17228, 17059, 16890, 16721, 16552, 16384};
+
+RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9] = {
+ {90, 151, -2472, 26787, 10819, -3468, 940, -94, 0}, {-98, 967, -4270, 19769, 19769, -4270, 967, -98, 0},
+ {-94, 940, -3468, 10819, 26787, -2472, 151, 90, 0}, {0, 503, -1550, 2739, 29447, 2739, -1550, 503, 0},
+ {0, 90, 151, -2472, 26787, 10819, -3468, 940, -94}, {0, -98, 967, -4270, 19769, 19769, -4270, 967, -98},
+ {0, -94, 940, -3468, 10819, 26787, -2472, 151, 90}};
+
+RAM_ALIGN const Word16 inter_filter[5][4][12] = {
+ {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}},
+ {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}},
+ {{2072, 8216, 12170, 8216, 2072, 0},
+ {1134, 6509, 11883, 9787, 3320, 140},
+ {503, 4831, 11057, 11057, 4831, 503},
+ {140, 3320, 9787, 11883, 6509, 1134}},
+ {{950, 3702, 7248, 8926, 7248, 3702, 950, 0},
+ {558, 2858, 6427, 8812, 7946, 4606, 1466, 102},
+ {281, 2106, 5530, 8479, 8479, 5530, 2106, 281},
+ {102, 1466, 4606, 7946, 8812, 6427, 2858, 558}},
+ {{355, 1183, 2515, 4068, 5333, 5822, 5333, 4068, 2515, 1183, 355, 0},
+ {231, 924, 2145, 3685, 5074, 5791, 5543, 4433, 2900, 1474, 510, 67},
+ {136, 700, 1797, 3293, 4771, 5697, 5697, 4771, 3293, 1797, 700, 136},
+ {67, 510, 1474, 2900, 4433, 5543, 5791, 5074, 3685, 2145, 924, 231}}};
+RAM_ALIGN const Word16 inter_filter_shift[5] = {1, 1, 2, 3, 5};
+RAM_ALIGN const Word16 inter_filter_len[5] = {4, 4, 6, 8, 12};
+
+RAM_ALIGN const Word16 tilt_filter[5][4][11] = {
+ {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}},
+ {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}},
+ {{11112, 14323, 2797, -356, -44},
+ {10998, 14271, 2906, -304, -38},
+ {10890, 14222, 3008, -255, -32},
+ {10788, 14175, 3104, -208, -26}},
+ {{8307, 12959, 5866, 1049, -283, -71, -9},
+ {8199, 12866, 5931, 1133, -242, -61, -8},
+ {8098, 12777, 5992, 1212, -203, -51, -6},
+ {8002, 12693, 6050, 1287, -166, -42, -5}},
+ {{5519, 9817, 7001, 3967, 1589, 259, -201, -88, -31, -8, -1},
+ {5433, 9706, 6991, 4014, 1651, 309, -172, -76, -27, -7, -1},
+ {5353, 9601, 6981, 4058, 1710, 356, -145, -64, -23, -6, -1},
+ {5277, 9501, 6970, 4100, 1767, 402, -118, -52, -19, -5, -1}}};
+RAM_ALIGN const Word16 tilt_filter_len[5] = {2, 2, 4, 6, 10};
+
+RAM_ALIGN const Word16 gain_scale_fac[4] = {13108, 11468, 9832, 8192};
+
+RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ] = {5120,
+ 10240,
+ 15360,
+ 20480,
+ 30720
+};
+
+RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ] = {20, 40, 60, 80, 120
+};
+
+/* set up of SNS VQ stages 1 ( split VQ) and SNS stage 2(Transformed PVQ) for bit rate 38 bits */
+
+/* trained gain set for DCT Q12 */
+RAM_ALIGN const Word16 sns_vq_reg_adj_gains[2] = {8915, 12054};
+RAM_ALIGN const Word16 sns_vq_reg_lf_adj_gains[4] = {6245, 15043, 17861, 21014};
+RAM_ALIGN const Word16 sns_vq_near_adj_gains[4] = {7099, 9132, 11253, 14808};
+RAM_ALIGN const Word16 sns_vq_far_adj_gains[8] = {4336, 5067, 5895, 8149, 10235, 12825, 16868, 19882};
+
+RAM_ALIGN const Word16 *const sns_gaintabPtr[4] = {sns_vq_reg_adj_gains, sns_vq_reg_lf_adj_gains, sns_vq_near_adj_gains,
+ sns_vq_far_adj_gains};
+RAM_ALIGN const Word16 sns_gainSz[4] = {2, 4, 4, 8};
+RAM_ALIGN const Word16 sns_gainMSBbits[4] = {1, 1, 2, 2};
+RAM_ALIGN const Word16 sns_gainLSBbits[4] = {0, 1, 0, 1};
+RAM_ALIGN const Word16 sns_Kval[4][2] = {{10, 1}, {10, 0}, {8, 0}, {6, 0}};
+RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2] = {
+ {4780008U >> 1, (2U * 6U)}, {4780008U >> 1, (2U)}, {30316544U >> 1, 0U}, {MPVQ_SZ_OUTL_FAR, 0U}};
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256] = {
+ 303712392, 109160791, -71161366, -182086260, -214684177, -193406093, -153520450, -101361734, 395293327,
+ 323657083, 128910102, -59488852, -164971858, -208829415, -200908713, -149907762, -293414324, -264613117,
+ -239872071, -257518046, -240785425, -182185002, -94683128, -6417929, 93105259, 128259784, 77206169,
+ -15381811, -86711449, -127822437, -144156883, -101748810, -174150364, -99370653, -46355110, -42048494,
+ -54086690, -49931794, -10514807, 13025043, 122762518, 233932163, 256230537, 207243559, 146760322,
+ 86903234, 4855873, -39875122, -337462040, -388124479, -269040331, -100785739, 59217144, 161317613,
+ 178164447, 163811504, -123774032, 84892061, 145943568, 81688751, 17605952, -39748467, -27784884,
+ 18109316, 106075262, 84342590, 52763395, 64425544, 60104730, 28150050, 881397, -11559399,
+ 194314494, 365609026, 310154713, 125500457, -36875504, -121074819, -126256135, -85053377, 106482242,
+ 1931812, -76213503, -87880462, -64351897, -23339746, 9128989, 39611134, 365643112, 397214108,
+ 248240465, 75602822, 18779354, 48270210, 92537937, 85871184, -71246823, -28546860, 773918,
+ 57025285, 63502293, 115278828, 159868294, 133706314, 226463440, 326973859, 312753384, 238885783,
+ 193825560, 204004473, 197567682, 131222320, -396188282, -213934330, -14753048, 52158227, 68844655,
+ 84303846, 110410429, 117560157, 13673880, 79169310, 83087169, 170095890, 324754621, 302223766,
+ 70670604, -53229612, 360045196, 178157942, 17473172, -45437142, -49421549, -25728189, -20774539,
+ -31434755, 647866186, 418689256, 187252080, 33594069, -52829955, -86363494, -86244384, -97065351,
+ 11789953, -76448652, -153687373, -224101311, -247677903, -210007831, -149983961, -71669806, 186699958,
+ 265947702, 149338424, -29542330, -104014124, -79733903, 18379464, 109822702, 51618245, -21553862,
+ -72392588, -71042662, 25559558, 343681831, 378354941, 88136873, 259345425, 404035869, 411436250,
+ 335692175, 259160465, 76793185, -108950139, -157896166, 23498902, -100733469, -139511132, -152441152,
+ -139852059, -2040916, 277895647, 460298246, -159473505, 49230106, 175768625, 225929624, 167907618,
+ 126483532, 110897463, 59049457, 340003306, 283568025, 169501437, 102208613, 70077483, 15928969,
+ -60712963, -93999711, 536723054, 547476463, 378877401, 231669479, 86858248, -44446002, -118654185,
+ -151259810, 68169532, 213189358, 232061142, 135146824, 50616355, 63937402, 145968142, 145970189,
+ 425278032, 437353108, 325116396, 240848448, 204249734, 157298757, 65685431, -8359023, 254228196,
+ 167918047, 79249020, 81652507, 117866118, 150206430, 136711039, 83275912, 127356599, 286205131,
+ 365535742, 371764419, 341298198, 271181905, 111406869, -3698627, -252365241, -169692913, 41798753,
+ 246517983, 302841086, 274903406, 294643934, 272005129, 33067993, 128261383, 204073729, 265277850,
+ 260441270, 299809987, 266873132, 170768802 };
+RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256] = {
+ 31142327, -135412629, -287525918, -318812488, -299361815, -292052248, -307447065, -339955249, -173817241,
+ -241497912, -253273077, -242922894, -236679593, -246180047, -242237472, -233108740, 18694612, -34653021,
+ -87349511, -143365648, -217337078, -293618146, -354009441, -399831591, -42481669, -64122205, -73975722,
+ -65067182, -31995949, -19196424, 9169576, 11852254, 118046962, 40042530, -122861082, -296146014,
+ -367947407, -384049364, -387676629, -396187390, -39822658, -130862945, -182344850, -132032812, -87638397,
+ -132873805, -216717640, -323078583, 45765709, 36091119, 7560964, 6698995, -12806126, -102027773,
+ -312402661, -506209524, -189555374, -199343014, -159187030, -83886299, 20656444, 77361286, 106715523,
+ 80069550, -30714319, -44791015, -108625274, -219563932, -252982160, -220783722, -188597085, -196852406,
+ -143812455, -190276467, -207892204, -195013074, -138489838, -92696486, -57558441, -66432436, -79321135,
+ -9552782, 46401689, 40339066, -150142954, -327610913, -299110559, -254354980, -113874897, -78279377,
+ 12085282, 113417337, 143039033, 98996714, 34438988, -66030204, 153101016, 129388157, 51198856,
+ -64806941, -243783312, -376184794, -434040973, -464270818, -50503881, 5713319, 69329858, 33784868,
+ -29015184, -71682211, -86004854, -116735202, 89255342, 147358670, 185680385, 180291129, 110458350,
+ 28974493, -54348215, -143647337, -110899539, -90084420, -30668159, 69656431, 183505023, 292625568,
+ 340370914, 295441538, 189258173, 101259479, -175222029, -251166616, -166441640, -170071209, -273362338,
+ -388808843, 48504518, -2952679, -77761569, -118034823, -114177011, -104608901, -98271929, -119232119,
+ 58716127, 40995519, -991583, -66524997, -108266901, -164325304, -228381893, -301307946, 86986552,
+ 91576640, 33990299, 9876306, 42173453, 31504911, 19407902, -9155262, 150216257, 165712633,
+ 79077091, -184136602, -318224471, -269482063, -223725572, -258546087, 19038449, -14852543, -37960074,
+ -885587, 38376778, 6179995, -80879122, -304095400, 67652037, 110995667, 150298671, 158261551,
+ 144938274, 93621729, -122480229, -480076341, -67253289, -43711762, 3768810, 35172367, 48397679,
+ 85311972, 128716474, 175483179, 503277534, 204470792, -61433556, -107201177, -51918012, -50452587,
+ -88293374, -172018761, -154697999, -148714432, -75512923, -29603347, -46955117, -101124035, -132687189,
+ -172859645, 138012394, 147331497, 103165859, 27659855, -46010607, -101326252, -139849742, -201777098,
+ 17291535, 92534989, 150789463, 175737342, 181881080, 191007103, 155298567, 54535272, 179896088,
+ 186558381, 140214471, 85338684, -36874140, -207934631, -327812990, -405951728, 287015358, 570037814,
+ 388874539, 125188990, -39301937, -108770623, -105880084, -125540975, 75810265, 213654461, 321816127,
+ 407615675, 357588710, 186971315, 54201685, -88083199, -56701695, 43775062, 186792575, 299502316,
+ 350549113, 357744389, 322261535, 236116337 };
+#endif
+
+RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256] = {
+ 4634, 1666, -1086, -2778, -3276, -2951, -2343, -1547, 6032, 4939, 1967, -908, -2517, -3186, -3066, -2287,
+ -4477, -4038, -3660, -3929, -3674, -2780, -1445, -98, 1421, 1957, 1178, -235, -1323, -1950, -2200, -1553,
+ -2657, -1516, -707, -642, -825, -762, -160, 199, 1873, 3570, 3910, 3162, 2239, 1326, 74, -608,
+ -5149, -5922, -4105, -1538, 904, 2462, 2719, 2500, -1889, 1295, 2227, 1246, 269, -607, -424, 276,
+ 1619, 1287, 805, 983, 917, 430, 13, -176, 2965, 5579, 4733, 1915, -563, -1847, -1927, -1298,
+ 1625, 29, -1163, -1341, -982, -356, 139, 604, 5579, 6061, 3788, 1154, 287, 737, 1412, 1310,
+ -1087, -436, 12, 870, 969, 1759, 2439, 2040, 3456, 4989, 4772, 3645, 2958, 3113, 3015, 2002,
+ -6045, -3264, -225, 796, 1050, 1286, 1685, 1794, 209, 1208, 1268, 2595, 4955, 4612, 1078, -812,
+ 5494, 2718, 267, -693, -754, -393, -317, -480, 9886, 6389, 2857, 513, -806, -1318, -1316, -1481,
+ 180, -1167, -2345, -3420, -3779, -3204, -2289, -1094, 2849, 4058, 2279, -451, -1587, -1217, 280, 1676,
+ 788, -329, -1105, -1084, 390, 5244, 5773, 1345, 3957, 6165, 6278, 5122, 3954, 1172, -1662, -2409,
+ 359, -1537, -2129, -2326, -2134, -31, 4240, 7024, -2433, 751, 2682, 3447, 2562, 1930, 1692, 901,
+ 5188, 4327, 2586, 1560, 1069, 243, -926, -1434, 8190, 8354, 5781, 3535, 1325, -678, -1811, -2308,
+ 1040, 3253, 3541, 2062, 772, 976, 2227, 2227, 6489, 6673, 4961, 3675, 3117, 2400, 1002, -128,
+ 3879, 2562, 1209, 1246, 1798, 2292, 2086, 1271, 1943, 4367, 5578, 5673, 5208, 4138, 1700, -56,
+ -3851, -2589, 638, 3762, 4621, 4195, 4496, 4150, 505, 1957, 3114, 4048, 3974, 4575, 4072, 2606};
+
+RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256] = {
+ 475, -2066, -4387, -4865, -4568, -4456, -4691, -5187, -2652, -3685, -3865, -3707, -3611, -3756, -3696, -3557,
+ 285, -529, -1333, -2188, -3316, -4480, -5402, -6101, -648, -978, -1129, -993, -488, -293, 140, 181,
+ 1801, 611, -1875, -4519, -5614, -5860, -5915, -6045, -608, -1997, -2782, -2015, -1337, -2027, -3307, -4930,
+ 698, 551, 115, 102, -195, -1557, -4767, -7724, -2892, -3042, -2429, -1280, 315, 1180, 1628, 1222,
+ -469, -683, -1657, -3350, -3860, -3369, -2878, -3004, -2194, -2903, -3172, -2976, -2113, -1414, -878, -1014,
+ -1210, -146, 708, 616, -2291, -4999, -4564, -3881, -1738, -1194, 184, 1731, 2183, 1511, 525, -1008,
+ 2336, 1974, 781, -989, -3720, -5740, -6623, -7084, -771, 87, 1058, 516, -443, -1094, -1312, -1781,
+ 1362, 2249, 2833, 2751, 1685, 442, -829, -2192, -1692, -1375, -468, 1063, 2800, 4465, 5194, 4508,
+ 2888, 1545, -2674, -3832, -2540, -2595, -4171, -5933, 740, -45, -1187, -1801, -1742, -1596, -1500, -1819,
+ 896, 626, -15, -1015, -1652, -2507, -3485, -4598, 1327, 1397, 519, 151, 644, 481, 296, -140,
+ 2292, 2529, 1207, -2810, -4856, -4112, -3414, -3945, 291, -227, -579, -14, 586, 94, -1234, -4640,
+ 1032, 1694, 2293, 2415, 2212, 1429, -1869, -7325, -1026, -667, 58, 537, 738, 1302, 1964, 2678,
+ 7679, 3120, -937, -1636, -792, -770, -1347, -2625, -2361, -2269, -1152, -452, -716, -1543, -2025, -2638,
+ 2106, 2248, 1574, 422, -702, -1546, -2134, -3079, 264, 1412, 2301, 2682, 2775, 2915, 2370, 832,
+ 2745, 2847, 2140, 1302, -563, -3173, -5002, -6194, 4380, 8698, 5934, 1910, -600, -1660, -1616, -1916,
+ 1157, 3260, 4911, 6220, 5456, 2853, 827, -1344, -865, 668, 2850, 4570, 5349, 5459, 4917, 3603};
+
+/* tables for MPVQ pulse enumeration */
+
+/* N=16, K=12 31.74 bits */
+RAM_ALIGN const UWord32 h_memN16K12[12 + 2] = {
+ 0U, 1U, 31U, 481U, 4991U, 39041U, 246047U,
+ 1303777U, 5984767U, 24331777U, 89129247U, 298199265U, 921406335U, /*U*/ 1326824512U};
+
+/*N=16,K=8,h_memN16K8={0U,1U,31U,481U,4991U,39041U,246047U,1303777U,5984767U, 12165888U,}; */
+
+/*N=10, K=20
+UWord32 h_memN10K20[20+2] =
+{
+ 0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U,
+ 3317445U,7059735U,14218905U,27298155U,50250765U,89129247U,152951073U,254831667U,413442773U,654862247U,
+ 507444884U
+};
+*/
+/*N=10, K=22 31.84 bits */
+RAM_ALIGN const UWord32 h_memN10K22[22 + 2] = {0U,
+ 1U,
+ 19U,
+ 181U,
+ 1159U,
+ 5641U,
+ 22363U,
+ 75517U,
+ 224143U,
+ 598417U,
+ 1462563U,
+ 3317445U,
+ 7059735U,
+ 14218905U,
+ 27298155U,
+ 50250765U,
+ 89129247U,
+ 152951073U,
+ 254831667U,
+ 413442773U,
+ 654862247U,
+ 1014889769U,
+ 1541911931U,
+ /*U*/ 1150204814U};
+/* N=10,K=10,h_memN10K10={0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U,1658722U,}; */
+
+/* N=6,K=2,*/
+RAM_ALIGN const UWord32 h_memN6K2[2 + 2] = {0U, 1U, 11U, /*U*/ 30U};
+/*N=6,K=1, h_memN6K1={0U,1U, 5U,}; */
+
+RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[M + 1] = {NULL /*0*/, NULL, NULL, NULL, NULL, NULL,
+ h_memN6K2, NULL, NULL, NULL, h_memN10K22, NULL,
+ NULL, NULL, NULL, NULL, h_memN16K12};
+
+/*maxK coefficents for MPVQ de-indexing lookup */
+RAM_ALIGN const Word16 tabledKMAX[M + 1] = {
+ 0, 0, 0, 0, 0, 0, 2 /*N=6*/, 0, 0, 0, 22 /*N=10*/, 0, 0, 0, 0, 0, 12 /*N=16*/
+};
+
+RAM_ALIGN const Word16 isqrt_Q16tab[1 + 64] = {/*table generated using ISqrt16 function + shift to Q16 */
+ 32767, 32767, 32767, 32767, 32766, 29308, 26754, 24770, 23169, 21844,
+ 20723, 19759, 18918, 18176, 17515, 16921, 16383, 15894, 15446, 15034,
+ 14654, 14300, 13972, 13665, 13377, 13107, 12852, 12612, 12385, 12169,
+ 11965, 11770, 11584, 11407, 11238, 11077, 10922, 10773, 10631, 10493,
+ 10361, 10234, 10112, 9993, 9879, 9769, 9662, 9559, 9459, 9362,
+ 9268, 9176, 9088, 9001, 8918, 8836, 8757, 8680, 8605, 8532,
+ 8460, 8390, 8323, 8256, 8191};
+
+#ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word32 isqrt_Q31tab[1 + 64] = {/* 2^31 / sqrt(idx) */
+ 2147483647, 2147483647, 1518500249, 1239850262, 1073741824, 960383883,
+ 876706528, 811672525, 759250124, 715827882, 679093956, 647490682,
+ 619925131, 595604800, 573939146, 554477893, 536870912, 520841288,
+ 506166749, 492666537, 480191941, 468619350, 457845052, 447781294,
+ 438353264, 429496729, 421156193, 413283420, 405836262, 398777702,
+ 392075078, 385699449, 379625062, 373828919, 368290407, 362990988,
+ 357913941, 353044136, 348367849, 343872591, 339546978, 335380599,
+ 331363920, 327488186, 323745341, 320127961, 316629189, 313242684,
+ 309962565, 306783378, 303700049, 300707858, 297802400, 294979564,
+ 292235509, 289566636, 286969573, 284441157, 281978417, 279578557,
+ 277238946, 274957105, 272730696, 270557508, 268435456 };
+#endif
+
+# ifdef ENABLE_HR_MODE
+RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680, 830},
+ {500, 1025, 1550, 2075, 2600, 3125},
+ {850, 1700, 2550, 3400, 4250, 5100},
+ {189, 164, 155, 151, 148, 146},
+ {1310, 3241, 5268, 7326, 9400, 11482}};
+# else
+RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680},
+ {500, 1025, 1550, 2075, 2600},
+ {850, 1700, 2550, 3400, 4250},
+ {189, 164, 155, 151, 148},
+ {1310, 3241, 5268, 7326, 9400}};
+# endif
+
+#if defined(CR8_A_PLC_FADEOUT_TUNING)
+const Word16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200};
+const Word16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7};
+#endif
diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h
new file mode 100644
index 0000000000000000000000000000000000000000..8dee7e6ebae1bfde803fc1787049f0ccced10e3e
--- /dev/null
+++ b/lib_lc3plus/constants.h
@@ -0,0 +1,402 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#include "defines.h"
+
+#include "basop_util_lc3plus.h"
+
+
+#ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[];
+
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2];
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2];
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2];
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2];
+#endif
+
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[6];
+# else
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[5];
+# endif
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ];
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960[6];
+# else
+extern RAM_ALIGN const Word16 *const LowDelayShapes_n960[6];
+# endif
+
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6];
+# else
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5];
+# endif
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ];
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6];
+# else
+extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6];
+# endif
+#ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6];
+#else
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5];
+#endif
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ];
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6];
+# else
+extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6];
+# endif
+
+# ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_7_5ms[5];
+# else
+extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_7_5ms[5];
+# endif
+
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[6];
+# else
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[5];
+# endif
+extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ];
+# endif
+
+extern RAM_ALIGN const Word16 NN_thresh;
+extern RAM_ALIGN const Word16 NN_thresh_exp;
+#ifdef CR8_E_TONE_DETECTOR
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 TD_HR_thresh_10ms;
+# ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word32 TD_HR_thresh_7_5ms;
+# endif
+extern RAM_ALIGN const Word32 TD_HR_thresh_5ms;
+extern RAM_ALIGN const Word32 TD_HR_thresh_2_5ms;
+# endif /* ENABLE_HR_MODE */
+#endif /* CR8_E_TONE_DETECTOR */
+extern RAM_ALIGN const Word32 BW_thresh_quiet[4];
+extern RAM_ALIGN const Word16 BW_thresh_quiet_exp;
+extern RAM_ALIGN const Word16 BW_thresh_brickwall[4];
+
+extern RAM_ALIGN const Word16 BW_cutoff_bin_all[];
+extern RAM_ALIGN const Word16 BW_cutoff_bits_all[];
+
+#ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 bands_number_2_5ms_HR[];
+#endif
+
+extern RAM_ALIGN const Word16 BW_brickwall_dist[4];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1];
+
+extern RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1];
+extern RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1];
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[];
+extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[];
+# endif
+#endif
+
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER];
+
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2];
+
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2];
+
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2];
+# endif
+
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER];
+
+
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER];
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[];
+extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[];
+# endif
+#endif
+
+extern RAM_ALIGN const Word16 Tab_esc_nb[4];
+
+extern RAM_ALIGN const Word8 ari_spec_lookup[4096];
+extern RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17];
+extern RAM_ALIGN const UWord16 ari_spec_freq[64][17];
+extern RAM_ALIGN const UWord16 ari_spec_bits[64][17];
+
+extern RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG];
+extern RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG];
+extern RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG];
+extern RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG];
+extern RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES];
+extern RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES];
+extern RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES];
+extern RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES];
+extern RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1];
+
+extern RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ];
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ];
+# endif
+#endif
+
+extern RAM_ALIGN const Word16 bands_nrg_scale[32];
+
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2];
+extern RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2];
+extern RAM_ALIGN const Word16 *const bands_offset_HR[2];
+# endif
+
+extern RAM_ALIGN const Word16 *const bands_offset[6];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS];
+
+extern RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const bands_offset_5ms[6];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 bands_number_2_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const bands_offset_2_5ms[6];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS];
+
+#ifdef CR8_G_ADD_75MS
+#ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word16 bands_number_7_5ms[];
+# ifndef GENERATE_BAND_TABLES
+extern RAM_ALIGN const Word16 *const bands_offset_7_5ms[5];
+# endif
+# ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word16 bands_number_7_5ms_HR[];
+# ifndef GENERATE_BAND_TABLES
+extern RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2];
+# endif
+# endif
+#endif
+#endif
+
+extern RAM_ALIGN const Word16 pitch_max[5];
+extern RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 TDC_high_16[11];
+extern RAM_ALIGN const Word16 TDC_high_32[11];
+extern RAM_ALIGN const Word16 TDC_high_16_harm[11];
+extern RAM_ALIGN const Word16 TDC_high_32_harm[11];
+
+extern RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ];
+
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_075_DMS_MODE
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS];
+extern RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ];
+# endif
+#endif
+
+extern RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_60_re[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_60_im[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_40_re[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_40_im[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_20_re[M];
+extern RAM_ALIGN const Word32 inv_odft_twiddle_20_im[M];
+
+#ifdef SUBSET_WB
+extern RAM_ALIGN const Word16 resamp_filt_16k[240];
+#else
+extern RAM_ALIGN const Word16 resamp_filt_16k[1];
+#endif
+#ifdef SUBSET_SSWB
+extern RAM_ALIGN const Word16 resamp_filt_24k[240];
+#else
+extern RAM_ALIGN const Word16 resamp_filt_24k[1];
+#endif
+#ifdef SUBSET_SWB
+extern RAM_ALIGN const Word16 resamp_filt_32k[240];
+#else
+extern RAM_ALIGN const Word16 resamp_filt_32k[1];
+#endif
+#ifdef SUBSET_FB
+extern RAM_ALIGN const Word16 resamp_filt_48k[240];
+#else
+extern RAM_ALIGN const Word16 resamp_filt_48k[1];
+#endif
+
+extern RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4];
+extern RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 highpass50_filt_num[3];
+extern RAM_ALIGN const Word16 highpass50_filt_den[2];
+
+extern RAM_ALIGN const Word16 olpa_ac_weighting[98];
+
+extern RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9];
+extern RAM_ALIGN const Word16 inter_filter[5][4][12];
+extern RAM_ALIGN const Word16 inter_filter_shift[5];
+extern RAM_ALIGN const Word16 inter_filter_len[5];
+extern RAM_ALIGN const Word16 tilt_filter[5][4][11];
+extern RAM_ALIGN const Word16 tilt_filter_len[5];
+extern RAM_ALIGN const Word16 gain_scale_fac[4];
+extern RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 sns_vq_reg_adj_scf[2];
+extern RAM_ALIGN const Word16 sns_vq_reg_lf_adj_scf[4];
+extern RAM_ALIGN const Word16 sns_vq_near_adj_scf[4];
+extern RAM_ALIGN const Word16 sns_vq_far_adj_scf[8];
+extern RAM_ALIGN const Word16 *const sns_gaintabPtr[4];
+extern RAM_ALIGN const Word16 sns_gainSz[4];
+extern RAM_ALIGN const Word16 sns_gainMSBbits[4];
+extern RAM_ALIGN const Word16 sns_gainLSBbits[4];
+extern RAM_ALIGN const Word16 sns_Kval[4][2];
+extern RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2];
+
+extern RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256];
+extern RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256];
+
+#ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256];
+extern RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256];
+#endif
+
+/* PVQ deindexing tables */
+extern RAM_ALIGN const UWord32 h_memN16K12[12 + 2];
+extern RAM_ALIGN const UWord32 h_memN10K22[22 + 2];
+extern RAM_ALIGN const UWord32 h_memN6K2[2 + 2];
+extern RAM_ALIGN const Word16 tabledKMAX[16 + 1];
+extern RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[16 + 1];
+
+extern RAM_ALIGN const Word16 isqrt_Q16tab[1 + SQRT_EN_MAX_FX];
+#ifdef ENABLE_HR_MODE
+extern RAM_ALIGN const Word32 isqrt_Q31tab[1 + SQRT_EN_MAX_FX];
+#endif
+
+extern RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ];
+
+extern RAM_ALIGN const Word16 sqrt_table_phecu[];
+extern RAM_ALIGN const Word16 POW_ATT_TABLE0[];
+extern RAM_ALIGN const Word16 POW_ATT_TABLE1[];
+#ifdef PLC2_FADEOUT_IN_MS
+#if PLC2_FADEOUT_IN_MS == 0
+extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3];
+#else
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+extern RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3];
+extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[1+24/2];
+#else
+extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[11];
+#endif
+
+#endif
+#else
+extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3];
+#endif
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+extern RAM_ALIGN const Word16 scATHFx[7];
+#endif
+
+extern RAM_ALIGN const Word16 e_tot_headroom[];
+extern RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[];
+
+extern RAM_ALIGN const Word16 num_FsByResQ0[5];
+extern RAM_ALIGN const Word16 *const LprotSzPtr;
+extern RAM_ALIGN const Word16 InvLprot_Q22[5];
+extern RAM_ALIGN const Word16 PhEcuFftScale[5];
+extern RAM_ALIGN const Word16 oneOverFrameQ15Tab[5];
+extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[];
+extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[];
+extern RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[];
+extern RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[];
+
+extern RAM_ALIGN const Word16 mdct_grp_bins_fx[];
+extern RAM_ALIGN const Word16 xavg_N_grp_fx[];
+extern RAM_ALIGN const Word16 spec_shape_headroom[];
+extern RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ];
+extern RAM_ALIGN const Word16 hamm_len2Tab[];
+
+#ifndef CR10_A_ATTENUATION_CURVE_SELECTOR
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30];
+extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60];
+#endif
+#endif
+extern RAM_ALIGN const Word16 gw_len_inv_shift_fx[];
+extern RAM_ALIGN const Word16 gwlpr_fx[];
+
+extern RAM_ALIGN const Word16 sin_quarterQ15_fx[];
+extern RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[];
+
+extern RAM_ALIGN const Word16 *const PhECU_wins[5][3];
+
+extern RAM_ALIGN const Word16 *const w_new[];
+extern RAM_ALIGN const Word16 *const w_old[];
+
+/* extern RAM_ALIGN const Word16 WORK_LEN[]; */
+extern RAM_ALIGN const Word16 COPY_LEN[];
+extern RAM_ALIGN const Word16 OLA_LEN[];
+
+#if defined(CR8_A_PLC_FADEOUT_TUNING)
+extern const Word16 plc_fadeout_param_maxlen[4];
+extern const Word16 plc_fadeout_param_maxbytes[4];
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+extern RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR;
+#endif
+
+#endif /* CONSTANTS_H */
diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c
new file mode 100644
index 0000000000000000000000000000000000000000..05f7cce492daf4a3dcb5a09d8e9eaebc2fc9f71d
--- /dev/null
+++ b/lib_lc3plus/cutoff_bandwidth.c
@@ -0,0 +1,26 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin)
+{
+ Counter i = 0;
+ if (len > bw_bin){
+ /* roll off */
+ for (i = -1; i < 3; i++) {
+ d_fx[bw_bin + i] = L_shr(d_fx[bw_bin + i], add(i, 2));
+ }
+
+ for (i = bw_bin + 3; i < len; i++) {
+ d_fx[i] = 0; move32();
+ }
+ }
+}
+
diff --git a/lib_lc3plus/dct2_fx.c b/lib_lc3plus/dct2_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c301c2aebc7d10e4d4c61522404e1c2f55519c5f
--- /dev/null
+++ b/lib_lc3plus/dct2_fx.c
@@ -0,0 +1,473 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void idct16_fx(const Word16 *in, Word16 *out)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
+ Word16 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
+ );
+
+ a8 = add(mult_r(in[1], 1136), mult_r(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */
+ a9 = add(mult_r(in[9], 8956), mult_r(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */
+ a10 = add(mult_r(in[5], 5461), mult_r(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */
+ a11 = add(mult_r(in[13], 11086), mult_r(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */
+ a12 = add(mult_r(in[3], 11086), mult_r(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */
+ a13 = add(mult_r(in[11], 5461), mult_r(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */
+ a14 = add(mult_r(in[7], 8956), mult_r(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */
+ a15 = add(mult_r(in[15], 1136), mult_r(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */
+
+ b4 = add(mult_r(in[2], 2260), mult_r(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */
+ b5 = add(mult_r(in[10], 9633), mult_r(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */
+ b6 = add(mult_r(in[6], 9633), mult_r(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */
+ b7 = add(mult_r(in[14], 2260), mult_r(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */
+ b8 = add(a9, a8);
+ b9 = sub(a8, a9);
+ b10 = sub(a11, a10);
+ b11 = add(a10, a11);
+ b12 = add(a13, a12);
+ b13 = sub(a12, a13);
+ b14 = sub(a15, a14);
+ b15 = add(a14, a15);
+
+ a0 = add(mult_r(in[0], 8192), mult_r(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */
+ a1 = add(mult_r(in[8], -8192), mult_r(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */
+ a2 = add(mult_r(in[4], 4433), mult_r(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */
+ a3 = add(mult_r(in[12], 4433), mult_r(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */
+ a4 = add(b5, b4);
+ a5 = sub(b4, b5);
+ a6 = sub(b7, b6);
+ a7 = add(b6, b7);
+ a8 = b8; move16();
+ a9 = add(mult_r(b9, -30274), mult_r(b14, 12540)); /* -CÏ€/8 C3Ï€/8 */
+ a10 = add(mult_r(b10, -12540), mult_r(b13, -30274)); /* -SÏ€/8 -S3Ï€/8 */
+ a11 = b11; move16();
+ a12 = b12; move16();
+ a13 = add(mult_r(b13, 12540), mult_r(b10, -30274)); /* C3Ï€/8 -CÏ€/8 */
+ a14 = add(mult_r(b14, 30274), mult_r(b9, 12540)); /* S3Ï€/8 SÏ€/8 */
+ a15 = b15; move16();
+
+ b0 = add(a3, a0);
+ b1 = add(a2, a1);
+ b2 = sub(a1, a2);
+ b3 = sub(a0, a3);
+ b4 = a4; move16();
+ b5 = add(mult_r(a5, -23170), mult_r(a6, 23170)); /* -CÏ€/4 CÏ€/4 */
+ b6 = add(mult_r(a6, 23170), mult_r(a5, 23170)); /* CÏ€/4 CÏ€/4 */
+ b7 = a7; move16();
+ b8 = add(a11, a8);
+ b9 = add(a10, a9);
+ b10 = sub(a9, a10);
+ b11 = sub(a8, a11);
+ b12 = sub(a15, a12);
+ b13 = sub(a14, a13);
+ b14 = add(a13, a14);
+ b15 = add(a12, a15);
+
+ a0 = add(b7, b0);
+ a1 = add(b6, b1);
+ a2 = add(b5, b2);
+ a3 = add(b4, b3);
+ a4 = sub(b3, b4);
+ a5 = sub(b2, b5);
+ a6 = sub(b1, b6);
+ a7 = sub(b0, b7);
+ a10 = add(mult_r(b10, -23170), mult_r(b13, 23170)); /* -CÏ€/4 CÏ€/4 */
+ a11 = add(mult_r(b11, -23170), mult_r(b12, 23170)); /* -CÏ€/4 CÏ€/4 */
+ a12 = add(mult_r(b12, 23170), mult_r(b11, 23170)); /* CÏ€/4 CÏ€/4 */
+ a13 = add(mult_r(b13, 23170), mult_r(b10, 23170)); /* CÏ€/4 CÏ€/4 */
+
+ out[0] = add(b15, a0); move16();
+ out[1] = add(b14, a1); move16();
+ out[2] = add(a13, a2); move16();
+ out[3] = add(a12, a3); move16();
+ out[4] = add(a11, a4); move16();
+ out[5] = add(a10, a5); move16();
+ out[6] = add(b9, a6); move16();
+ out[7] = add(b8, a7); move16();
+ out[8] = sub(a7, b8); move16();
+ out[9] = sub(a6, b9); move16();
+ out[10] = sub(a5, a10); move16();
+ out[11] = sub(a4, a11); move16();
+ out[12] = sub(a3, a12); move16();
+ out[13] = sub(a2, a13); move16();
+ out[14] = sub(a1, b14); move16();
+ out[15] = sub(a0, b15); move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+void dct32_fx(const Word32 *in, Word32 *out)
+{
+ Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
+ Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;);
+
+ a0 = L_add(in[15], in[0]);
+ a1 = L_add(in[14], in[1]);
+ a2 = L_add(in[13], in[2]);
+ a3 = L_add(in[12], in[3]);
+ a4 = L_add(in[11], in[4]);
+ a5 = L_add(in[10], in[5]);
+ a6 = L_add(in[9], in[6]);
+ a7 = L_add(in[8], in[7]);
+ a10 = L_sub(in[5], in[10]);
+ a11 = L_sub(in[4], in[11]);
+ a12 = L_sub(in[3], in[12]);
+ a13 = L_sub(in[2], in[13]);
+
+ b0 = L_add(a7, a0);
+ b1 = L_add(a6, a1);
+ b2 = L_add(a5, a2);
+ b3 = L_add(a4, a3);
+ b4 = L_sub(a3, a4);
+#ifdef CR9_C_FIX_DCT2_OVERFLOW
+ b5 = L_sub_sat(a2, a5);
+#else
+ b5 = L_sub(a2, a5);
+#endif
+#ifdef CR9_C_FIX_DCT2_OVERFLOW
+ b6 = L_sub_sat(a1, a6);
+#else
+ b6 = L_sub(a1, a6);
+#endif
+ b7 = L_sub(a0, a7);
+ b8 = L_sub(in[7], in[8]);
+ b9 = L_sub(in[6], in[9]);
+ b10 = L_add(Mpy_32_16_lc3plus(a10, -23170), Mpy_32_16_lc3plus(a13, 23170)); /* -CÏ€/4 CÏ€/4 */
+ b11 = L_add(Mpy_32_16_lc3plus(a11, -23170), Mpy_32_16_lc3plus(a12, 23170)); /* -CÏ€/4 CÏ€/4 */
+ b12 = L_add(Mpy_32_16_lc3plus(a12, 23170), Mpy_32_16_lc3plus(a11, 23170)); /* CÏ€/4 CÏ€/4 */
+ b13 = L_add(Mpy_32_16_lc3plus(a13, 23170), Mpy_32_16_lc3plus(a10, 23170)); /* CÏ€/4 CÏ€/4 */
+ b14 = L_sub(in[1], in[14]);
+ b15 = L_sub(in[0], in[15]);
+
+ a0 = L_add(b3, b0);
+ a1 = L_add(b2, b1);
+ a2 = L_sub(b1, b2);
+ a3 = L_sub_sat(b0, b3);
+ a4 = b4;
+ move16();
+ a5 = L_add(Mpy_32_16_lc3plus(b5, -23170), Mpy_32_16_lc3plus(b6, 23170)); /* -CÏ€/4 CÏ€/4 */
+ a6 = L_add(Mpy_32_16_lc3plus(b6, 23170), Mpy_32_16_lc3plus(b5, 23170)); /* CÏ€/4 CÏ€/4 */
+ a7 = b7;
+ move16();
+ a8 = L_add(b11, b8);
+ a9 = L_add(b10, b9);
+ a10 = L_sub(b9, b10);
+ a11 = L_sub(b8, b11);
+ a12 = L_sub(b15, b12);
+ a13 = L_sub(b14, b13);
+ a14 = L_add(b13, b14);
+ a15 = L_add(b12, b15);
+
+ out[0] = L_add(Mpy_32_16_lc3plus(a0, 8192), Mpy_32_16_lc3plus(a1, 8192));
+ move16(); /* Cπ/4/√8 Cπ/4/√8 */
+ out[8] = L_add(Mpy_32_16_lc3plus(a1, -8192), Mpy_32_16_lc3plus(a0, 8192));
+ move16(); /* -Cπ/4/√8 Cπ/4/√8 */
+ out[4] = L_add(Mpy_32_16_lc3plus(a2, 4433), Mpy_32_16_lc3plus(a3, 10703));
+ move16(); /* Sπ/8/√8 Cπ/8/√8 */
+ out[12] = L_add(Mpy_32_16_lc3plus(a3, 4433), Mpy_32_16_lc3plus(a2, -10703));
+ move16(); /* C3π/8/√8 -S3π/8/√8 */
+ b4 = L_add(a5, a4);
+ b5 = L_sub(a4, a5);
+ b6 = L_sub_sat(a7, a6);
+ b7 = L_add(a6, a7);
+ b8 = a8;
+ move16();
+ b9 = L_add(Mpy_32_16_lc3plus(a9, -30274), Mpy_32_16_lc3plus(a14, 12540)); /* -CÏ€/8 SÏ€/8 */
+ b10 = L_add(Mpy_32_16_lc3plus(a10, -12540), Mpy_32_16_lc3plus(a13, -30274)); /* -SÏ€/8 -CÏ€/8 */
+ b11 = a11;
+ move16();
+ b12 = a12;
+ move16();
+ b13 = L_add(Mpy_32_16_lc3plus(a13, 12540), Mpy_32_16_lc3plus(a10, -30274)); /* C3Ï€/8 -S3Ï€/8 */
+ b14 = L_add(Mpy_32_16_lc3plus(a14, 30274), Mpy_32_16_lc3plus(a9, 12540)); /* S3Ï€/8 C3Ï€/8 */
+ b15 = a15;
+ move16();
+
+ out[2] = L_add(Mpy_32_16_lc3plus(b4, 2260), Mpy_32_16_lc3plus(b7, 11363));
+ move16(); /* Sπ/16/√8 Cπ/16/√8 */
+ out[10] = L_add(Mpy_32_16_lc3plus(b5, 9633), Mpy_32_16_lc3plus(b6, 6436));
+ move16(); /* S5π/16/√8 C5π/16/√8 */
+ out[6] = L_add(Mpy_32_16_lc3plus(b6, 9633), Mpy_32_16_lc3plus(b5, -6436));
+ move16(); /* C3π/16/√8 -S3π/16/√8 */
+ out[14] = L_add(Mpy_32_16_lc3plus(b7, 2260), Mpy_32_16_lc3plus(b4, -11363));
+ move16(); /* C7π/16/√8 -S7π/16/√8 */
+
+ a8 = L_add_sat(b9, b8);
+ a9 = L_sub_sat(b8, b9);
+ a10 = L_sub_sat(b11, b10);
+ a11 = L_add_sat(b10, b11);
+ a12 = L_add_sat(b13, b12);
+ a13 = L_sub_sat(b12, b13);
+ a14 = L_sub_sat(b15, b14);
+ a15 = L_add_sat(b14, b15);
+
+ out[1] = L_add(Mpy_32_16_lc3plus(a8, 1136), Mpy_32_16_lc3plus(a15, 11529));
+ move16(); /* Sπ/32/√8 Cπ/32/√8 */
+ out[9] = L_add(Mpy_32_16_lc3plus(a9, 8956), Mpy_32_16_lc3plus(a14, 7350));
+ move16(); /* S9π/32/√8 C9π/32/√8 */
+ out[5] = L_add(Mpy_32_16_lc3plus(a10, 5461), Mpy_32_16_lc3plus(a13, 10217));
+ move16(); /* S5π/32/√8 C5π/32/√8 */
+ out[13] = L_add(Mpy_32_16_lc3plus(a11, 11086), Mpy_32_16_lc3plus(a12, 3363));
+ move16(); /* S13π/32/√8 C13π/32/√8 */
+ out[3] = L_add(Mpy_32_16_lc3plus(a12, 11086), Mpy_32_16_lc3plus(a11, -3363));
+ move16(); /* C3π/32/√8 -S3π/32/√8 */
+ out[11] = L_add(Mpy_32_16_lc3plus(a13, 5461), Mpy_32_16_lc3plus(a10, -10217));
+ move16(); /* C11π/32/√8 -S11π/32/√8 */
+ out[7] = L_add(Mpy_32_16_lc3plus(a14, 8956), Mpy_32_16_lc3plus(a9, -7350));
+ move16(); /* C7π/32/√8 -S7π/32/√8 */
+ out[15] = L_add(Mpy_32_16_lc3plus(a15, 1136), Mpy_32_16_lc3plus(a8, -11529));
+ move16(); /* C15π/32/√8 -S15/32/√8 */
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+void idct32_fx(const Word32 *in, Word32 *out)
+{
+ Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
+ Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;);
+
+ a8 = L_add(Mpy_32_16_lc3plus(in[1], 1136), Mpy_32_16_lc3plus(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */
+ a9 = L_add(Mpy_32_16_lc3plus(in[9], 8956), Mpy_32_16_lc3plus(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */
+ a10 = L_add(Mpy_32_16_lc3plus(in[5], 5461), Mpy_32_16_lc3plus(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */
+ a11 = L_add(Mpy_32_16_lc3plus(in[13], 11086), Mpy_32_16_lc3plus(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */
+ a12 = L_add(Mpy_32_16_lc3plus(in[3], 11086), Mpy_32_16_lc3plus(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */
+ a13 = L_add(Mpy_32_16_lc3plus(in[11], 5461), Mpy_32_16_lc3plus(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */
+ a14 = L_add(Mpy_32_16_lc3plus(in[7], 8956), Mpy_32_16_lc3plus(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */
+ a15 = L_add(Mpy_32_16_lc3plus(in[15], 1136), Mpy_32_16_lc3plus(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */
+
+ b4 = L_add(Mpy_32_16_lc3plus(in[2], 2260), Mpy_32_16_lc3plus(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */
+ b5 = L_add(Mpy_32_16_lc3plus(in[10], 9633), Mpy_32_16_lc3plus(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */
+ b6 = L_add(Mpy_32_16_lc3plus(in[6], 9633), Mpy_32_16_lc3plus(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */
+ b7 = L_add(Mpy_32_16_lc3plus(in[14], 2260), Mpy_32_16_lc3plus(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */
+ b8 = L_add(a9, a8);
+ b9 = L_sub(a8, a9);
+ b10 = L_sub(a11, a10);
+ b11 = L_add(a10, a11);
+ b12 = L_add(a13, a12);
+ b13 = L_sub(a12, a13);
+ b14 = L_sub(a15, a14);
+ b15 = L_add(a14, a15);
+
+ a0 = L_add(Mpy_32_16_lc3plus(in[0], 8192), Mpy_32_16_lc3plus(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */
+ a1 = L_add(Mpy_32_16_lc3plus(in[8], -8192), Mpy_32_16_lc3plus(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */
+ a2 = L_add(Mpy_32_16_lc3plus(in[4], 4433), Mpy_32_16_lc3plus(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */
+ a3 = L_add(Mpy_32_16_lc3plus(in[12], 4433), Mpy_32_16_lc3plus(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */
+ a4 = L_add(b5, b4);
+ a5 = L_sub(b4, b5);
+ a6 = L_sub(b7, b6);
+ a7 = L_add(b6, b7);
+ a8 = b8;
+ move32();
+ a9 = L_add(Mpy_32_16_lc3plus(b9, -30274), Mpy_32_16_lc3plus(b14, 12540)); /* -CÏ€/8 C3Ï€/8 */
+ a10 = L_add(Mpy_32_16_lc3plus(b10, -12540), Mpy_32_16_lc3plus(b13, -30274)); /* -SÏ€/8 -S3Ï€/8 */
+ a11 = b11;
+ move32();
+ a12 = b12;
+ move32();
+ a13 = L_add(Mpy_32_16_lc3plus(b13, 12540), Mpy_32_16_lc3plus(b10, -30274)); /* C3Ï€/8 -CÏ€/8 */
+ a14 = L_add(Mpy_32_16_lc3plus(b14, 30274), Mpy_32_16_lc3plus(b9, 12540)); /* S3Ï€/8 SÏ€/8 */
+ a15 = b15;
+ move32();
+
+ b0 = L_add(a3, a0);
+ b1 = L_add(a2, a1);
+ b2 = L_sub(a1, a2);
+ b3 = L_sub(a0, a3);
+ b4 = a4;
+ move32();
+ b5 = L_add(Mpy_32_16_lc3plus(a5, -23170), Mpy_32_16_lc3plus(a6, 23170)); /* -CÏ€/4 CÏ€/4 */
+ b6 = L_add(Mpy_32_16_lc3plus(a6, 23170), Mpy_32_16_lc3plus(a5, 23170)); /* CÏ€/4 CÏ€/4 */
+ b7 = a7;
+ move32();
+ b8 = L_add(a11, a8);
+ b9 = L_add(a10, a9);
+ b10 = L_sub(a9, a10);
+ b11 = L_sub(a8, a11);
+ b12 = L_sub(a15, a12);
+ b13 = L_sub(a14, a13);
+ b14 = L_add(a13, a14);
+ b15 = L_add(a12, a15);
+
+ a0 = L_add(b7, b0);
+ a1 = L_add(b6, b1);
+ a2 = L_add(b5, b2);
+ a3 = L_add(b4, b3);
+ a4 = L_sub(b3, b4);
+ a5 = L_sub(b2, b5);
+ a6 = L_sub(b1, b6);
+ a7 = L_sub(b0, b7);
+ a10 = L_add(Mpy_32_16_lc3plus(b10, -23170), Mpy_32_16_lc3plus(b13, 23170)); /* -CÏ€/4 CÏ€/4 */
+ a11 = L_add(Mpy_32_16_lc3plus(b11, -23170), Mpy_32_16_lc3plus(b12, 23170)); /* -CÏ€/4 CÏ€/4 */
+ a12 = L_add(Mpy_32_16_lc3plus(b12, 23170), Mpy_32_16_lc3plus(b11, 23170)); /* CÏ€/4 CÏ€/4 */
+ a13 = L_add(Mpy_32_16_lc3plus(b13, 23170), Mpy_32_16_lc3plus(b10, 23170)); /* CÏ€/4 CÏ€/4 */
+
+ out[0] = L_add(b15, a0);
+ move32();
+ out[1] = L_add(b14, a1);
+ move32();
+ out[2] = L_add(a13, a2);
+ move32();
+ out[3] = L_add(a12, a3);
+ move32();
+ out[4] = L_add(a11, a4);
+ move32();
+ out[5] = L_add(a10, a5);
+ move32();
+ out[6] = L_add(b9, a6);
+ move32();
+ out[7] = L_add(b8, a7);
+ move32();
+ out[8] = L_sub(a7, b8);
+ move32();
+ out[9] = L_sub(a6, b9);
+ move32();
+ out[10] = L_sub(a5, a10);
+ move32();
+ out[11] = L_sub(a4, a11);
+ move32();
+ out[12] = L_sub(a3, a12);
+ move32();
+ out[13] = L_sub(a2, a13);
+ move32();
+ out[14] = L_sub(a1, b14);
+ move32();
+ out[15] = L_sub(a0, b15);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+void idct32_32_fx(const Word32 *in, Word32 *out)
+{
+ Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15;
+ Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;);
+
+ /*round(sin(pi*(1:16)/32)/sqrt(8)*2^31) =
+ 74419526 148122351 220398677 290552444 357908031 421816769 481663180 536870912
+ 586908283 631293407 669598830 701455651 726557070 744661347 755594128 759250125
+ */
+ /*ound(cos(pi*(1:16)/32)/sqrt(8)*2^31) =
+ 755594128 744661347 726557070 701455651 669598830 631293407 586908283 536870912
+ 481663180 421816769 357908031 290552444 220398677 148122351 74419526 0
+ */
+
+ a8 = L_add(Mpy_32_32_lc3plus(in[1], 74419526), Mpy_32_32_lc3plus(in[15], -755594128)); /* Sπ/32/√8 -S15π/32/√8 */
+ a9 = L_add(Mpy_32_32_lc3plus(in[9], 586908283), Mpy_32_32_lc3plus(in[7], -481663180)); /* S9π/32/√8 -S7π/32/√8 */
+ a10 = L_add(Mpy_32_32_lc3plus(in[5], 357908031), Mpy_32_32_lc3plus(in[11], -669598830)); /* S5π/32/√8 -S11π/32/√8 */
+ a11 = L_add(Mpy_32_32_lc3plus(in[13], 726557070), Mpy_32_32_lc3plus(in[3], -220398677)); /* S13π/32/√8 -S3π/32/√8 */
+
+ a12 = L_add(Mpy_32_32_lc3plus(in[3], 726557070), Mpy_32_32_lc3plus(in[13], 220398677)); /* C3π/32/√8 C13π/32/√8 */
+ a13 = L_add(Mpy_32_32_lc3plus(in[11], 357908031), Mpy_32_32_lc3plus(in[5], 669598830)); /* C11π/32/√8 C5π/32/√8 */
+ a14 = L_add(Mpy_32_32_lc3plus(in[7], 586908283), Mpy_32_32_lc3plus(in[9], 481663180)); /* C7π/32/√8 C9π/32/√8 */
+ a15 = L_add(Mpy_32_32_lc3plus(in[15], 74419526), Mpy_32_32_lc3plus(in[1], 755594128)); /* C15π/32/√8 Cπ/32/√8 */
+
+ b4 = L_add(Mpy_32_32_lc3plus(in[2], 148122351), Mpy_32_32_lc3plus(in[14], -744661347)); /* Sπ/16/√8 -S7π/16/√8 */
+ b5 = L_add(Mpy_32_32_lc3plus(in[10], 631293407), Mpy_32_32_lc3plus(in[6], -421816769)); /* S5π/16/√8 -S3π/16/√8 */
+ b6 = L_add(Mpy_32_32_lc3plus(in[6], 631293407), Mpy_32_32_lc3plus(in[10], 421816769)); /* C3π/16/√8 C5π/16/√8 */
+ b7 = L_add(Mpy_32_32_lc3plus(in[14], 148122351), Mpy_32_32_lc3plus(in[2], 744661347)); /* C7π/16/√8 Cπ/16/√8 */
+ b8 = L_add(a9, a8);
+ b9 = L_sub(a8, a9);
+ b10 = L_sub(a11, a10);
+ b11 = L_add(a10, a11);
+ b12 = L_add(a13, a12);
+ b13 = L_sub(a12, a13);
+ b14 = L_sub(a15, a14);
+ b15 = L_add(a14, a15);
+
+ a0 = L_add(Mpy_32_32_lc3plus(in[0], 536870912), Mpy_32_32_lc3plus(in[8], 536870912)); /* Cπ/4/√8 Cπ/4/√8 */
+ a1 = L_add(Mpy_32_32_lc3plus(in[8], -536870912), Mpy_32_32_lc3plus(in[0], 536870912)); /* -Cπ/4/√8 Cπ/4/√8 */
+ a2 = L_add(Mpy_32_32_lc3plus(in[4], 290552444), Mpy_32_32_lc3plus(in[12], -701455651)); /* Sπ/8/√8 -S3π/8/√8 */
+ a3 = L_add(Mpy_32_32_lc3plus(in[12], 290552444), Mpy_32_32_lc3plus(in[4], 701455651)); /* C3π/8/√8 Cπ/8/√8 */
+ a4 = L_add(b5, b4);
+ a5 = L_sub(b4, b5);
+ a6 = L_sub(b7, b6);
+ a7 = L_add(b6, b7);
+ a8 = b8;
+ move32();
+ a9 = L_add(Mpy_32_32_lc3plus(b9, -1984016189), Mpy_32_32_lc3plus(b14, 821806413)); /* -CÏ€/8 C3Ï€/8 */
+ a10 = L_add(Mpy_32_32_lc3plus(b10, -821806413), Mpy_32_32_lc3plus(b13, -1984016189)); /* -SÏ€/8 -S3Ï€/8 */
+ a11 = b11;
+ move32();
+ a12 = b12;
+ move32();
+ a13 = L_add(Mpy_32_32_lc3plus(b13, 821806413), Mpy_32_32_lc3plus(b10, -1984016189)); /* C3Ï€/8 -CÏ€/8 */
+ a14 = L_add(Mpy_32_32_lc3plus(b14, 1984016189), Mpy_32_32_lc3plus(b9, 821806413)); /* S3Ï€/8 SÏ€/8 */
+ a15 = b15;
+ move32();
+
+ b0 = L_add(a3, a0);
+ b1 = L_add(a2, a1);
+ b2 = L_sub(a1, a2);
+ b3 = L_sub(a0, a3);
+ b4 = a4;
+ move32();
+ b5 = L_add(Mpy_32_32_lc3plus(a5, -1518500250), Mpy_32_32_lc3plus(a6, 1518500250)); /* -CÏ€/4 CÏ€/4 */
+ b6 = L_add(Mpy_32_32_lc3plus(a6, 1518500250), Mpy_32_32_lc3plus(a5, 1518500250)); /* CÏ€/4 CÏ€/4 */
+ b7 = a7;
+ move32();
+ b8 = L_add(a11, a8);
+ b9 = L_add(a10, a9);
+ b10 = L_sub(a9, a10);
+ b11 = L_sub(a8, a11);
+ b12 = L_sub(a15, a12);
+ b13 = L_sub(a14, a13);
+ b14 = L_add(a13, a14);
+ b15 = L_add(a12, a15);
+
+ a0 = L_add(b7, b0);
+ a1 = L_add(b6, b1);
+ a2 = L_add(b5, b2);
+ a3 = L_add(b4, b3);
+ a4 = L_sub(b3, b4);
+ a5 = L_sub(b2, b5);
+ a6 = L_sub(b1, b6);
+ a7 = L_sub(b0, b7);
+ a10 = L_add(Mpy_32_32_lc3plus(b10, -1518500250), Mpy_32_32_lc3plus(b13, 1518500250)); /* -CÏ€/4 CÏ€/4 */
+ a11 = L_add(Mpy_32_32_lc3plus(b11, -1518500250), Mpy_32_32_lc3plus(b12, 1518500250)); /* -CÏ€/4 CÏ€/4 */
+ a12 = L_add(Mpy_32_32_lc3plus(b12, 1518500250), Mpy_32_32_lc3plus(b11, 1518500250)); /* CÏ€/4 CÏ€/4 */
+ a13 = L_add(Mpy_32_32_lc3plus(b13, 1518500250), Mpy_32_32_lc3plus(b10, 1518500250)); /* CÏ€/4 CÏ€/4 */
+
+ out[0] = L_add(b15, a0);
+ move32();
+ out[1] = L_add(b14, a1);
+ move32();
+ out[2] = L_add(a13, a2);
+ move32();
+ out[3] = L_add(a12, a3);
+ move32();
+ out[4] = L_add(a11, a4);
+ move32();
+ out[5] = L_add(a10, a5);
+ move32();
+ out[6] = L_add(b9, a6);
+ move32();
+ out[7] = L_add(b8, a7);
+ move32();
+ out[8] = L_sub(a7, b8);
+ move32();
+ out[9] = L_sub(a6, b9);
+ move32();
+ out[10] = L_sub(a5, a10);
+ move32();
+ out[11] = L_sub(a4, a11);
+ move32();
+ out[12] = L_sub(a3, a12);
+ move32();
+ out[13] = L_sub(a2, a13);
+ move32();
+ out[14] = L_sub(a1, b14);
+ move32();
+ out[15] = L_sub(a0, b15);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
diff --git a/lib_lc3plus/dct4_fx.c b/lib_lc3plus/dct4_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..af98a395d38df7178606d9c683dc9b1210147671
--- /dev/null
+++ b/lib_lc3plus/dct4_fx.c
@@ -0,0 +1,228 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "rom_basop_util.h"
+
+
+void dct_IV(Word32 *pDat, /* i/o: pointer to data buffer */
+ Word16 *pDat_e, /* i/o: pointer to data exponent */
+ Word16 L, /* i : length of block */
+#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+# ifdef ENABLE_HR_MODE
+ Word16 hrmode, /* indicate high precision usage */
+# endif
+#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+ Word32 *workBuffer) /* : size of L */
+
+{
+ Word16 sin_step;
+ Word16 idx;
+ Word16 M_var;
+ Word16 M2;
+
+ Word32 *pDat_0;
+ Word32 *pDat_1;
+
+ Word32 accu1;
+ Word32 accu2;
+ Word32 accu3;
+ Word32 accu4;
+
+ Counter i;
+
+#ifdef ENABLE_HR_MODE
+ const PWord32 *twiddle;
+ const PWord32 *sin_twiddle;
+#else
+ const PWord16 *twiddle;
+ const PWord16 *sin_twiddle;
+#endif
+
+#ifdef ENABLE_DCTIV_RESCALE
+ Word16 scale;
+#endif
+
+#ifdef DYNMEM_COUNT
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_In("dct_IV", sizeof(struct {
+ Word16 sin_step;
+ Word16 idx;
+ Counter i;
+ Word16 M_var;
+ Word16 M2;
+
+ Word32 *pDat_0;
+ Word32 *pDat_1;
+
+ Word32 accu1;
+ Word32 accu2;
+ Word32 accu3;
+ Word32 accu4;
+
+ const PWord32 *twiddle;
+ const PWord32 *sin_twiddle;
+ }));
+
+#else
+ Dyn_Mem_In("dct_IV", sizeof(struct {
+ Word16 sin_step;
+ Word16 idx;
+ Counter i;
+ Word16 M_var;
+ Word16 M2;
+
+ Word32 *pDat_0;
+ Word32 *pDat_1;
+
+ Word32 accu1;
+ Word32 accu2;
+ Word32 accu3;
+ Word32 accu4;
+
+ const PWord16 *twiddle;
+ const PWord16 *sin_twiddle;
+ }));
+#endif /* ENABLE_HR_MODE */
+#endif /* DYNMEM_COUNT */
+
+ M_var = shr_pos_pos(L, 1);
+ M2 = sub(M_var, 1);
+
+ BASOP_getTables(&twiddle, &sin_twiddle, &sin_step, L);
+
+ pDat_0 = &pDat[0];
+ pDat_1 = &pDat[L - 2];
+
+ FOR (i = 0; i < M2; i += 2)
+ {
+#ifdef ENABLE_HR_MODE
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ if (hrmode) {
+ cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im);
+ cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im);
+ } else {
+ cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], round_fx_sat(twiddle[i].v.re), round_fx_sat(twiddle[i].v.im));
+ cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], round_fx_sat(twiddle[i + 1].v.re), round_fx_sat(twiddle[i + 1].v.im));
+ }
+# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+ cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im);
+ cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im);
+# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+#else
+ cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im);
+ cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im);
+#endif
+
+ pDat_0[0] = accu2; move32();
+ pDat_0[1] = accu1; move32();
+ pDat_1[0] = accu4; move32();
+ pDat_1[1] = L_negate(accu3); move32();
+
+ pDat_0 = pDat_0 + 2;
+ pDat_1 = pDat_1 - 2;
+ }
+
+#ifdef ENABLE_DCTIV_RESCALE
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ if (hrmode)
+# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+ {
+
+ scale = s_max(getScaleFactor32_lc3plus(pDat, L), 0); move16();
+
+ FOR (i = 0; i < L; i++)
+ {
+ pDat[i] = L_shl_pos(pDat[i], scale); move32();
+ }
+
+ *pDat_e = sub(*pDat_e, scale); move16();
+ }
+#endif
+
+ BASOP_cfft_lc3plus(&pDat[0], &pDat[1], M_var, 2, pDat_e, workBuffer);
+
+ pDat_0 = &pDat[0];
+ pDat_1 = &pDat[L - 2];
+
+ idx = sin_step;
+ M2 = sub(shr_pos_pos(add(M_var, 1), 1), 1);
+
+ /* Sin and Cos values are 0.0f and 1.0f */
+#ifdef ENABLE_HR_MODE
+ cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#else
+ cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#endif
+
+ pDat_1[1] = L_negate(L_shr_pos(pDat_0[1], 1)); move32();
+ pDat_0[0] = L_shr_pos(pDat_0[0], 1); move32();
+
+ FOR (i = 1; i < M2; i++)
+ {
+ pDat_0[1] = accu3; move32();
+ pDat_1[0] = accu4; move32();
+
+ pDat_0 = pDat_0 + 2;
+ pDat_1 = pDat_1 - 2;
+
+#ifdef ENABLE_HR_MODE
+ cplxMpy32_32_32_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#else
+ cplxMpy32_32_16_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#endif
+
+ idx += sin_step;
+
+#ifdef ENABLE_HR_MODE
+ cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#else
+ cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#endif
+
+ pDat_1[1] = L_negate(accu1); move32();
+ pDat_0[0] = accu2; move32();
+ }
+
+ pDat_0[1] = accu3; move32();
+ pDat_1[0] = accu4; move32();
+
+ pDat_0 = pDat_0 + 2;
+ pDat_1 = pDat_1 - 2;
+
+#ifdef ENABLE_HR_MODE
+ cplxMpy32_32_32_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#else
+ cplxMpy32_32_16_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im);
+#endif
+
+/* Last Sin and Cos value pair are the same */
+#ifdef ENABLE_HR_MODE
+ accu1 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[0], TWIDDLE), 1);
+ accu2 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[1], TWIDDLE), 1);
+#else
+ accu1 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[0], TWIDDLE), 1);
+ accu2 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[1], TWIDDLE), 1);
+#endif
+
+ pDat_1[0] = L_add(accu1, accu2); move32();
+ pDat_0[1] = L_sub(accu1, accu2); move32();
+
+ pDat_1[1] = L_negate(accu3); move32();
+ pDat_0[0] = accu4; move32();
+
+ /* twiddeling scale is 2 */
+ *pDat_e = add(*pDat_e, 2); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c
new file mode 100644
index 0000000000000000000000000000000000000000..48512f9fef2bd74b66a327e14d9bc2960311fbbe
--- /dev/null
+++ b/lib_lc3plus/dec_entropy.c
@@ -0,0 +1,387 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits);
+
+static Word16 ac_dec_split_st2VQ_CW( /* local BER flag */
+ const Word32 L_cwRx, /* max 25 bits */
+ const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB,
+ Word16 *submodeLSB);
+
+void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits,
+ Word16 L_spec, Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters,
+ Word16 *lsbMode, Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx,
+ Word16 *gg_idx, Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx,
+ Word16 frame_dms)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 L, submodeLSB;
+ Word32 tmp32, tmp32lim;
+ Word16 gain_e, gain, submodeMSB, BER_detect;
+ Counter n;
+ UWord8 *ptr;
+ );
+
+ ptr = bytes;
+ *bp_side = shr_pos(sub(nbbits, 1), 3);
+ *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3))));
+
+ /* Cutoff-detection */
+ IF (BW_cutoff_bits > 0)
+ {
+ *BW_cutoff_idx = read_indice(ptr, bp_side, mask_side, BW_cutoff_bits);
+ /* check for bitflips */
+ IF (sub(fs_idx, *BW_cutoff_idx) < 0)
+ {
+ *BW_cutoff_idx = fs_idx;
+ *bfi = 1; move16();
+ Dyn_Mem_Deluxe_Out();
+ return;
+ }
+ }
+ ELSE
+ {
+ *BW_cutoff_idx = fs_idx;
+ }
+
+ /* Number of TNS filters */
+ IF (sub(*BW_cutoff_idx, 3) >= 0 && frame_dms >= 50)
+ {
+ *tns_numfilters = 2; move16();
+ }
+ ELSE
+ {
+ *tns_numfilters = 1; move16();
+ }
+
+ /* Decode number of ntuples */
+ L = sub(14, norm_s(negate(L_spec)));
+ n = read_indice(ptr, bp_side, mask_side, L);
+ n = add(n, 1);
+ *lastnz = shl_pos(n, 1);
+ IF (sub(*lastnz, L_spec) > 0)
+ {
+ *bfi = 1; move16();
+ Dyn_Mem_Deluxe_Out();
+ return;
+ }
+
+ /* Mode bit */
+ *lsbMode = read_bit(ptr, bp_side, mask_side);
+
+ /* Decode global-gain */
+ *gg_idx = read_indice(ptr, bp_side, mask_side, 8); move16();
+ tmp32 = L_shl_pos(L_mult0(*gg_idx, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
+ gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */
+ gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000)));
+ assert(gain >= 0); /* JSv, check if shr_pos(gain,1) is more appropriate) */
+ gain = shr_r(gain, 1);
+ gain_e = add(gain_e, 1);
+
+ /* Decode TNS on/off flag */
+ tns_order[1] = 0; move16(); /* fix problem with uninitialized memory */
+ FOR (n = 0; n < *tns_numfilters; n++)
+ {
+ tns_order[n] = read_bit(ptr, bp_side, mask_side); move16();
+ }
+
+ /* LTPF on/off */
+#ifdef ENABLE_HR_MODE
+ ltpf_idx[0] = read_bit(ptr, bp_side, mask_side); move16();
+#else
+ ltpf_idx[0] = read_indice(ptr, bp_side, mask_side, 1); move16();
+#endif
+
+ /* Decode SNS VQ parameters - 1st stage (10 bits) */
+#ifdef ENABLE_HR_MODE
+ L = read_indice(ptr, bp_side, mask_side, 5 + 5);
+ L_scf_idx[0] = L_deposit_l(s_and(L, 0x1F)); /* stage1 LF 5 bits */
+ L_scf_idx[1] = L_deposit_l(shr_pos(L, 5)); /* stage1 HF 5 bits */
+#else
+ L_scf_idx[0] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 LF 5 bits */
+ L_scf_idx[1] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 HF 5 bits */
+#endif
+
+ /* Decode SNS VQ parameters - 2nd stage side-info (3-4 bits) */
+ submodeMSB = read_bit(ptr, bp_side, mask_side); /* submodeMSB 1 bit */
+ L_scf_idx[2] = L_deposit_l(shl_pos(submodeMSB, 1));
+ ASSERT(sns_gainMSBbits[L_scf_idx[2]] > 0);
+ L_scf_idx[3] = L_deposit_l(
+ read_indice(ptr, bp_side, mask_side, sns_gainMSBbits[L_scf_idx[2]])); /* gains or gain MSBs 1-2 bits */
+ L_scf_idx[4] = read_bit(ptr, bp_side, mask_side); /* shape LS 1 bit */
+
+ /* Decode SNS VQ parameters - 2nd stage data (24-25 bits) */
+ IF (submodeMSB == 0)
+ { /* shape_j = 0, or 1 */
+ /* regular mode A,B indexes integer multiplexed, total 24.x bits MPVQ codeword section A and codeword for
+ * section B */
+ /* regular mode mode shape index total 24.9999 bits MPVQ codeword */
+ tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 13));
+ tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 13)); move16(); /*for ber state */
+ BER_detect =
+ ac_dec_split_st2VQ_CW( /* local BER flag */
+ tmp32, /* L_cwRx max 25 bits */
+ sns_MPVQ_Sz[0][0], UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* 12+2 = 14 */
+ (&L_scf_idx[5]), /* shape A */
+ (&L_scf_idx[6]), /* shape B or gain LSB */
+ &submodeLSB /* total submode update below */
+ );
+ IF (submodeLSB != 0)
+ { /* add gainLSB bit */
+ L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_scf_idx[6]);
+ L_scf_idx[6] = -2L;
+ }
+ }
+ ELSE
+ { /* shape_j = 2 or 3 */
+ ASSERT(submodeMSB == 1);
+ /* outlier mode shape index total 23.8536 + 19.5637 (19.5637 < (log2(2.^24 -2.^23.8537)) bits MPVQ
+ * codeword */
+ tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 12));
+ tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 12));
+ L_scf_idx[5] = tmp32; move32(); /*shape outl_near or outl_far */
+ submodeLSB = 0; move16();
+ BER_detect = 0; move16();
+ tmp32lim = L_add(sns_MPVQ_Sz[2][0], L_shl_pos(sns_MPVQ_Sz[3][0], 1));
+ IF (L_sub(tmp32, tmp32lim) >= 0)
+ {
+ BER_detect = 1; move16();
+ }
+ ELSE
+ {
+ tmp32 = L_sub(tmp32, sns_MPVQ_Sz[2][0]); /* a potential high index is computed */
+ IF (tmp32 >= 0)
+ {
+ submodeLSB = 1; move16();
+ ASSERT(tmp32 >= 0 && tmp32 < (Word32)(2 * sns_MPVQ_Sz[3][0]));
+ L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_and(tmp32, 0x1)); /* add LSB_gain bit to gain MSBs */
+ L_scf_idx[5] = L_shr_pos(tmp32, 1); /* MPVQ index with offset and gainLSB removed */
+ L_scf_idx[6] = -2L; move32();
+ }
+ ELSE
+ {
+ L_scf_idx[6] = -1L; move32();
+ }
+ }
+ }
+ L_scf_idx[2] =
+ L_add(L_scf_idx[2], L_deposit_l(submodeLSB)); /* decoder internal signal shape_j = submode 0..3 to VQ */
+
+ IF (BER_detect > 0)
+ {
+ *bfi = 1; move16();
+ Dyn_Mem_Deluxe_Out();
+ return;
+ }
+
+ /* LTPF data */
+ IF (ltpf_idx[0] != 0)
+ {
+#ifdef ENABLE_HR_MODE
+ L = read_indice(ptr, bp_side, mask_side, 1+9); move16();
+ ltpf_idx[1] = s_and(L, 1); move16();
+ ltpf_idx[2] = shr_pos(L, 1); move16();
+#else
+ ltpf_idx[1] = read_indice(ptr, bp_side, mask_side, 1); move16();
+ ltpf_idx[2] = read_indice(ptr, bp_side, mask_side, 9); move16();
+
+#endif
+ }
+ ELSE
+ {
+ ltpf_idx[1] = 0; move16();
+ ltpf_idx[2] = 0; move16();
+ }
+
+ /* Decode noise-fac */
+ *fac_ns_idx = read_indice(ptr, bp_side, mask_side, 3); move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+#ifdef ENABLE_PADDING
+int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled,
+ Word16 *total_padding, Word16 *np_zero)
+{
+ Word16 lastnz_threshold;
+ Word16 padding_len_bits, padding_len;
+
+ Word16 bp_side;
+ Word16 nbbytes = shr(nbbits,3);
+
+ Word16 mask_side;
+ UWord8 *ptr = bytes;
+
+ Word16 lastnz;
+ Word16 nbits = sub(14, norm_s(negate(L_spec)));
+ if (sub(nbbits, nbits) < 0)
+ {
+ return 1;
+ }
+ *np_zero = 0;
+
+ *total_padding = 0;
+
+ bp_side = shr_pos(sub(nbbits, 1), 3);
+ mask_side = shl(1, sub(8, sub(nbbits, shl_pos(bp_side, 3))));
+
+ test();
+ IF (sub(bp_side, 19) < 0 || sub(bp_side, LC3PLUS_MAX_BYTES ) >= 0) {
+ return 1;
+ }
+
+ ptr = bytes;
+
+ IF (BW_cutoff_bits > 0)
+ {
+ read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits);
+ move16();
+ }
+
+ lastnz = read_indice(ptr, &bp_side, &mask_side, nbits);
+ move16();
+
+ lastnz_threshold = sub(shl(1, nbits), 2);
+
+ WHILE (lastnz == lastnz_threshold)
+ {
+ padding_len_bits = sub(sub(12, nbits), BW_cutoff_bits);
+
+ /*Read padding length*/
+ padding_len = read_indice(ptr, &bp_side, &mask_side, padding_len_bits);
+ move16();
+
+ /* Read 4 reserved bits */
+ read_indice(ptr, &bp_side, &mask_side, 4);
+ move16();
+
+ IF (ep_enabled == 0)
+ {
+ /* Discard padding length bytes */
+ bp_side = sub(bp_side, padding_len);
+ *total_padding = add(add(*total_padding, padding_len), 2); move16();
+ }
+ ELSE
+ {
+ *total_padding = add(*total_padding, 2); move16();
+ *np_zero = add(*np_zero, padding_len); move16();
+ }
+
+ /* test if we have less than 20 bytes left; if so frame is broken */
+ IF (sub(sub(nbbytes,add(*total_padding,*np_zero)),20) < 0) {
+ return 1;
+ }
+
+ /* Read bandwidth bits */
+ IF (BW_cutoff_bits > 0)
+ {
+ read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits);
+ move16();
+ }
+
+ lastnz = read_indice(ptr, &bp_side, &mask_side, nbits);
+ move16();
+ }
+
+ IF (ep_enabled != 0)
+ {
+ *total_padding = add(*total_padding, *np_zero); move16();
+ }
+ return 0;
+}
+#endif
+
+static __forceinline Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 indice, bit;
+ Counter i;
+ );
+
+ indice = read_bit(ptr, bp, mask);
+
+ FOR (i = 1; i < numbits; i++)
+ {
+ bit = read_bit(ptr, bp, mask);
+ indice = add(indice, lshl_pos(bit, i));
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ return indice;
+}
+
+static __forceinline Word16 ac_dec_split_st2VQ_CW( /* local BER flag */
+ const Word32 L_cwRx, /* max 25 bits */
+ const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB,
+ Word16 *submodeLSB)
+{
+ /* demultiplex: L_cwRx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */
+ Word16 start, fin, ind;
+ Word32 L_tmp, L_max_size;
+ Counter i;
+
+ L_max_size = (Word32)UL_Mpy_32_32((UWord32)L_szB, (UWord32)L_szA); /* may be tabled */
+
+ /* section B ind larger than 13 out of the possible 14 = 0..13 */
+ IF (L_sub(L_cwRx, L_max_size) >= 0)
+ {
+ *L_cwA = L_deposit_l(0);
+ *L_cwB = L_deposit_l(0);
+ *submodeLSB = 0; move16();
+ return (Word16)1; /* set berFlag and exit */
+ }
+
+ /*initial binary split of cw, select top or low half */
+ start = 0; move16();
+
+ ASSERT((L_szB & 0x1L) == 0); /* this middle split only works if L_szB is even */
+ if (L_sub(L_cwRx, L_shr_pos(L_max_size, 1)) >= 0)
+ {
+ start = L_shr_pos(L_szB, 1); /* top half start index */
+ }
+
+ /*linear loop over a low or a high section */
+ ind = start; move16();
+ L_tmp = L_negate(L_cwRx); /* search from negative side */
+
+ L_tmp = L_add(L_tmp, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)start), (UWord32)L_szA));
+ /* start is 0 or 7 */ /*non-fractional mult is (int)start * L_szA */
+
+ /* a short linear run over ceil(szB/2) = 7 values */
+
+ fin = add(start, shr_pos(L_szB, 1));
+ FOR (i = start; i < fin; i++)
+ {
+ ind = add(ind, 1);
+ L_tmp = L_add(L_tmp, L_szA);
+ if (L_tmp > 0)
+ {
+ ind = sub(ind, 1); /* passed criteria point, keep index */
+ }
+ }
+
+ *L_cwB = L_deposit_l(ind);
+ *L_cwA = L_sub(L_cwRx, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)ind),
+ (UWord32)L_szA)); /* non-fractional mult; (int)ind * L_szA */
+
+ ASSERT(*L_cwA >= 0 && *L_cwA < L_szA);
+ ASSERT(*L_cwB >= 0 && *L_cwB < L_szB);
+
+ *submodeLSB = 0;
+ *L_cwB = L_sub(*L_cwB, 2);
+ if (*L_cwB < 0)
+ {
+ *submodeLSB = 1; move16();
+ }
+ *L_cwB = L_mac0(*L_cwB, 2, *submodeLSB); /* add back gain ind if needed */
+
+ return 0; /* no BER */
+}
diff --git a/lib_lc3plus/dec_lc3.c b/lib_lc3plus/dec_lc3.c
new file mode 100644
index 0000000000000000000000000000000000000000..40818106e9af14028a673d24210b68f3b56c8f36
--- /dev/null
+++ b/lib_lc3plus/dec_lc3.c
@@ -0,0 +1,788 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static int Dec_LC3PLUS_Channel(LC3PLUS_Dec *decoder, int channel, int bits_per_sample, UWord8 *bs_in, void *s_out, Word16 bfi,
+ Word8 *scratchBuffer)
+{
+ Word16 scale;
+ Word32 offset;
+ Word16 fill_bits;
+ Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp = 0;
+ Word16 bp_side, mask_side;
+ Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf;
+ Word16 zero_frame = 0;
+#ifdef ENABLE_RFRAME
+ Word16 rframe = 0;
+#endif
+ Word16 ltpf_idx[3];
+ Word16 spec_inv_idx = 0;
+ Counter i;
+
+ /* Buffers */
+ Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX];
+ UWord8 *resBitBuf;
+#ifdef ENABLE_HR_MODE
+ Word32 *sqQdec;
+#else
+ Word16 * sqQdec;
+ Word16 * int_scf_fx;
+#endif
+ Word16 * x_fx, *indexes;
+ Word16 scf_q[M];
+ Word32 * L_scf_idx;
+ Word32 * q_d_fx;
+ Word8 * currentScratch;
+ DecSetup *h_DecSetup = decoder->channel_setup[channel];
+#ifdef ENABLE_HR_MODE
+ Word32 *x_fx_ip;
+ Word32 *int_scf_fx_ip;
+ Word32 scf_q_ip[M];
+#endif
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Counter i;
+ Word16 scale;
+ Word32 offset;
+ Word16 fill_bits;
+ Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp;
+ Word16 bp_side, mask_side;
+ Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf;
+ Word16 zero_frame;
+ Word16 ltpf_idx[3];
+#ifdef ENABLE_RFRAME
+ Word16 rframe;
+#endif
+ Word16 spec_inv_idx;
+
+ /* Buffers */
+ Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX];
+ UWord8 *resBitBuf;
+#ifdef ENABLE_HR_MODE
+ Word32 *sqQdec;
+#else
+ Word16 *sqQdec;
+#endif
+ Word16 *int_scf_fx, *x_fx, *indexes;
+ Word32 *L_scf_idx;
+ Word32 *q_d_fx;
+ Word8 * currentScratch;
+ Word16 scf_q[M];
+#ifdef ENABLE_HR_MODE
+ Word32 scf_q_ip[M];
+#endif
+ };
+ Dyn_Mem_In("Dec_LC3_Channel", sizeof(struct _dynmem));
+#endif
+
+#ifdef DISABLE_PLC
+ UNUSED(decoder->plcMeth);
+#endif
+
+
+ /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole decoding process */
+ q_d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */
+#ifdef ENABLE_HR_MODE
+ /* allocate memory for residual bits */
+ if (decoder->hrmode)
+ {
+ resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) *
+ decoder->frame_length);
+ basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * MAX_RESBITS_LEN);
+ }
+ else
+#endif
+ {
+ resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) *
+ decoder->frame_length); /* Size = 2 * NPRM_RESQ = 2 * MAX_LEN bytes for
+ normal case and 2*MAX_RESBITS_LEN for hrmode */
+ basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * 2 * decoder->frame_length);
+ }
+
+#ifdef ENABLE_HR_MODE
+ indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * MAX_RESBITS_LEN);
+#else
+ indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * 2 * decoder->frame_length);
+#endif
+ memset(indexes, 0, sizeof(*indexes) * TNS_NUMFILTERS_MAX * MAXLAG);
+
+ /* indexes Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */
+
+ L_scf_idx = scratchAlign(indexes, sizeof(*indexes) * TNS_NUMFILTERS_MAX *
+ MAXLAG); /* Size = 4 * SCF_MAX_PARAM = 28 bytes -> aligned to 32 bytes */
+ sqQdec = scratchAlign(L_scf_idx, sizeof(*L_scf_idx) * (SCF_MAX_PARAM)); /* Size = 2 * MAX_LEN bytes */
+ int_scf_fx_exp = scratchAlign(sqQdec, sizeof(*sqQdec) * decoder->frame_length); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+#ifndef ENABLE_HR_MODE
+ int_scf_fx = scratchAlign(int_scf_fx_exp,
+ sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+#endif
+#ifdef ENABLE_HR_MODE
+ x_fx =
+ scratchAlign(int_scf_fx_exp, sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2
+ * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */
+#else
+ x_fx =
+ scratchAlign(q_d_fx, sizeof(*q_d_fx) * decoder->frame_length); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2
+ * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */
+#endif
+
+#ifdef ENABLE_HR_MODE
+ x_fx_ip = scratchAlign(x_fx, sizeof(*x_fx) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len));
+ int_scf_fx_ip = scratchAlign(x_fx_ip, sizeof(*x_fx_ip) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len));
+
+ currentScratch = scratchAlign(int_scf_fx_ip, sizeof(*int_scf_fx_ip) * 2 * MAX_BANDS_NUMBER); /* Size = 4 * MAX_LEN */
+#else
+ currentScratch = scratchAlign(x_fx, sizeof(*x_fx) * 4 * MAX_LEN); /* Size = 4 * MAX_LEN */
+#endif
+
+#ifdef DISABLE_PLC
+ memset(q_d_fx, 0, decoder->frame_length * sizeof(*q_d_fx));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Decoder");
+#endif
+
+#ifdef ENABLE_RFRAME
+ IF (sub(bfi, 3) == 0)
+ {
+ bfi = 2;
+ move16();
+ rframe = 1;
+ move16();
+ }
+#endif
+
+ if (bfi != 1)
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("Dec(bfi=0)");
+#endif
+ }
+ else
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("Dec(bfi=1)");
+#endif
+ }
+
+#ifdef WMOPS
+ BASOP_sub_start("Entropy dec");
+#endif
+ IF (sub(bfi, 1) != 0)
+ {
+ processDecoderEntropy_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx,
+ decoder->BW_cutoff_bits, &tns_numfilters, &lsbMode, &lastnz, &bfi, tns_order,
+ &fac_ns_idx, &gg_idx, &BW_cutoff_idx, ltpf_idx, L_scf_idx, decoder->frame_dms);
+ BW_cutoff_idx_nf = BW_cutoff_idx;
+ move16();
+ }
+#ifdef WMOPS
+ BASOP_sub_end(); /* Entropy dec */
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Ari dec");
+#endif
+ IF (sub(bfi, 1) != 0)
+ {
+ processAriDecoder_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx,
+ h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order,
+ fac_ns_idx, gg_idx, decoder->frame_dms,
+ decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &spec_inv_idx, &scale,
+ &fill_bits, sqQdec, &nf_seed, resBitBuf, indexes, &zero_frame, currentScratch
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+
+#ifdef ENABLE_RFRAME
+ test();test();
+ IF (sub(rframe, 1) == 0 && zero_frame == 0 && sub(bfi, 1) != 0)
+ {
+ bfi = 2;
+ move16();
+ Word16 max_bw_stopband = BW_cutoff_bin_all[BW_cutoff_idx];
+ SWITCH (decoder->frame_dms)
+ {
+#ifdef ENABLE_025_DMS_MODE
+ case 25:
+ max_bw_stopband = shr_pos(max_bw_stopband, 2);
+ BREAK;
+#endif
+#ifdef ENABLE_050_DMS_MODE
+ case 50:
+ max_bw_stopband = shr_pos(max_bw_stopband, 1);
+ BREAK;
+#endif
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ max_bw_stopband = add(shr_pos(max_bw_stopband, 2), add(shr_pos(max_bw_stopband, 2), shr_pos(max_bw_stopband, 2)));
+ BREAK;
+#endif
+ case 100:
+ BREAK;
+ }
+
+ spec_inv_idx = s_max(lastnz, max_bw_stopband);
+ move16();
+ }
+#endif
+
+ IF (bfi == 0)
+ {
+ processAriDecoderScaling_fx(sqQdec, decoder->yLen, q_d_fx, &q_fx_exp);
+ }
+ }
+#ifdef WMOPS
+ BASOP_sub_end(); /* Ari dec */
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("SnsQuantScfDec");
+#endif
+ IF (sub(bfi, 1) != 0)
+ {
+ /* currentScratch Size = 96 bytes */
+#ifdef ENABLE_HR_MODE
+ processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q_ip, currentScratch);
+ downshift_w32_arr(scf_q_ip, scf_q, 15, M); /* required for PLC */
+#else
+ processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q, currentScratch);
+#endif
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("PLC::ComputeStabFac");
+#endif
+ if (h_DecSetup->plcAd)
+ {
+ processPLCcomputeStabFac_main(scf_q, h_DecSetup->plcAd->old_scf_q, h_DecSetup->plcAd->old_old_scf_q, bfi,
+ h_DecSetup->prev_bfi, h_DecSetup->prev_prev_bfi, &h_DecSetup->plcAd->stab_fac);
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Partial Concealment");
+#endif
+ IF (sub(bfi, 1) != 0)
+ {
+ scale = 32767;
+ move16();
+
+ IF (h_DecSetup->plcAd)
+ {
+ scale = h_DecSetup->plcAd->stab_fac;
+ }
+
+ processPCmain_fx(rframe, &bfi, decoder->yLen, decoder->frame_dms, h_DecSetup->q_old_res_fx,
+ &h_DecSetup->q_old_res_fx_exp, sqQdec, h_DecSetup->q_old_d_fx, spec_inv_idx, ltpf_idx[0],
+ scale, q_d_fx, &q_fx_exp, gg_idx, h_DecSetup->quantizedGainOff, &h_DecSetup->prev_gg,
+ &h_DecSetup->prev_gg_e, &BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx,
+ &h_DecSetup->prev_fac_ns_fx, &h_DecSetup->pc_nbLostFramesInRow);
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ IF (sub(bfi, 1) != 0)
+ {
+#ifdef WMOPS
+ BASOP_sub_start("Residual dec");
+#endif
+ processResidualDecoding_fx(q_d_fx, q_fx_exp, decoder->yLen, resBitBuf, fill_bits
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Noisefill");
+#endif
+ /* currentScratch Size = 2 * MAX_LEN bytes */
+ IF (zero_frame == 0)
+ {
+ processNoiseFilling_fx(q_d_fx, nf_seed, q_fx_exp, fac_ns_idx, BW_cutoff_idx_nf, decoder->frame_dms,
+ h_DecSetup->prev_fac_ns_fx, spec_inv_idx, currentScratch
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("applyGlobalGain");
+#endif
+ processApplyGlobalGain_fx(q_d_fx, &q_fx_exp, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Tns_dec");
+#endif
+ /* currentScratch Size = 48 bytes */
+ processTnsDecoder_fx(indexes, q_d_fx, decoder->yLen, tns_order, &q_fx_exp, BW_cutoff_idx, decoder->frame_dms,
+ currentScratch
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef ENABLE_HR_MODE
+#ifdef WMOPS
+ BASOP_sub_start("SnsInterpScfDec");
+#endif
+ processSnsInterpolateScf_fx(scf_q_ip, int_scf_fx_ip, int_scf_fx_exp, 0, decoder->bands_number, currentScratch);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Mdct shaping_dec");
+#endif
+ processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp);
+
+ processMdctShaping_fx(q_d_fx, int_scf_fx_ip, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+#else
+#ifdef WMOPS
+ BASOP_sub_start("SnsInterpScfDec");
+#endif
+ /* currentScratch Size = 128 bytes */
+ processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 0, decoder->bands_number, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Mdct shaping_dec");
+#endif
+ processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp);
+ processMdctShaping_fx(q_d_fx, int_scf_fx, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+ /* end int_scf_fx */
+#endif /* ENABLE_HR_MODE */
+ }
+
+ /* x_fx_ip will be used to store h_DecSetup->stDec_ola_mem_fx returned by PLCmain_fx*/
+ /* This will be upshifted to 32 bit overlap buffer outside of the PLCmain function */
+#ifdef ENABLE_HR_MODE
+ Word16 *plc_ola_mem = (Word16 *)x_fx_ip;
+ IF(sub(bfi, 1) == 0)
+ {
+ FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++)
+ {
+ plc_ola_mem[i] = round_fx(h_DecSetup->stDec_ola_mem_fx[i]);
+ }
+ }
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("PLC::Main");
+#endif
+ /* currentScratch Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */
+ processPLCmain_fx(decoder->plcMeth, &h_DecSetup->concealMethod, &h_DecSetup->nbLostFramesInRow, bfi,
+ h_DecSetup->prev_bfi, decoder->frame_length, decoder->la_zeroes, decoder->W_fx, x_fx,
+#ifdef ENABLE_HR_MODE
+ plc_ola_mem,
+#else
+ h_DecSetup->stDec_ola_mem_fx,
+#endif
+ &h_DecSetup->stDec_ola_mem_fx_exp, h_DecSetup->q_old_d_fx,
+ &h_DecSetup->q_old_fx_exp, q_d_fx, &q_fx_exp, decoder->yLen, decoder->fs_idx,
+ decoder->bands_offset, decoder->bands_number, &h_DecSetup->plc_damping, h_DecSetup->ltpf_mem_pitch_int,
+ h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ns_cum_alpha, &h_DecSetup->ns_seed, h_DecSetup->plcAd,
+ decoder->frame_dms, currentScratch, &h_DecSetup->pc_nbLostFramesInRow
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ , h_DecSetup->rel_pitch_change
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , decoder->alpha_type_2_table
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef ENABLE_HR_MODE
+ IF(sub(bfi, 1) == 0)
+ {
+ FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++)
+ {
+ h_DecSetup->stDec_ola_mem_fx[i] = L_deposit_h(plc_ola_mem[i]);
+ }
+ }
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("PLC/PC::DampingScrambling");
+#endif
+ if (h_DecSetup->plcAd)
+ {
+ processPLCDampingScrambling_main_fx(
+ bfi, h_DecSetup->concealMethod, h_DecSetup->nbLostFramesInRow, &h_DecSetup->plcAd->cum_fflcAtten,
+ h_DecSetup->pc_nbLostFramesInRow, &h_DecSetup->ns_seed, &h_DecSetup->pc_seed,
+ h_DecSetup->ltpf_mem_pitch_int, ltpf_idx[0], q_d_fx, &q_fx_exp, h_DecSetup->q_old_d_fx,
+ &h_DecSetup->q_old_fx_exp, decoder->yLen, h_DecSetup->plcAd->stab_fac, decoder->frame_dms,
+ &h_DecSetup->plcAd->cum_fading_slow, &h_DecSetup->plcAd->cum_fading_fast, spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , h_DecSetup->plcAd->plc_fadeout_type
+#endif
+ );
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Imdct");
+#endif
+ /* currentScratch Size = 4 * MAX_LEN */
+ ProcessingIMDCT(q_d_fx, &q_fx_exp, decoder->W_fx, h_DecSetup->stDec_ola_mem_fx, &h_DecSetup->stDec_ola_mem_fx_exp,
+#ifdef ENABLE_HR_MODE
+ x_fx_ip,
+#else
+ x_fx,
+#endif
+ decoder->W_size, decoder->frame_length, decoder->stDec_ola_mem_fx_len, decoder->frame_dms,
+ h_DecSetup->concealMethod, bfi, h_DecSetup->prev_bfi, h_DecSetup->nbLostFramesInRow,
+ h_DecSetup->plcAd,
+ currentScratch
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+
+#ifdef ENABLE_HR_MODE
+ IF(sub(bfi, 1) != 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0)
+ {
+ round_w32tow16_arr(x_fx_ip, x_fx, decoder->frame_length);
+ }
+ ELSE
+ {
+ FOR(i = 0; i < decoder->frame_length; i++)
+ {
+ x_fx_ip[i] = L_deposit_h(x_fx[i]);
+ }
+ }
+#endif /* ENABLE_HR_MODE */
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("PLC::Update");
+#endif
+
+ processPLCupdate_fx(h_DecSetup->plcAd, x_fx, q_fx_exp, h_DecSetup->concealMethod, decoder->frame_length,
+ decoder->fs_idx, &h_DecSetup->nbLostFramesInRow, &h_DecSetup->prev_prev_bfi,
+ &h_DecSetup->prev_bfi, bfi, scf_q, &h_DecSetup->ns_cum_alpha
+#ifdef ENABLE_HR_MODE
+ , decoder->hrmode
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("LtpfDec");
+#endif
+ /* currentScratch Size = 0.5 * MAX_LEN + 20 bytes */
+ process_ltpf_decoder_fx(&q_fx_exp, decoder->frame_length, decoder->ltpf_mem_x_len, decoder->fs_idx,
+ decoder->ltpf_mem_y_len, &h_DecSetup->ltpf_mem_e, x_fx, h_DecSetup->ltpf_mem_x, x_fx,
+ h_DecSetup->ltpf_mem_y, ltpf_idx[0], ltpf_idx[1], ltpf_idx[2],
+ &h_DecSetup->ltpf_mem_pitch_int, &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain,
+ &h_DecSetup->ltpf_mem_active, h_DecSetup->ltpf_scale_fac_idx, bfi,
+ h_DecSetup->concealMethod,
+ h_DecSetup->plc_damping, &h_DecSetup->ltpf_mem_scale_fac_idx,
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms,
+#endif
+ currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef ENABLE_HR_MODE
+ IF (!(decoder->hrmode))
+ {
+ FOR (i = 0; i < decoder->frame_length; i++)
+ {
+ x_fx_ip[i] = L_deposit_h(x_fx[i]);
+ }
+ }
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Output scaling");
+#endif
+ {
+ scale = sub(sub(31 + 16, bits_per_sample), q_fx_exp);
+ offset = L_shr_sat(32768, sub(16, scale));
+ IF (bits_per_sample == 16)
+ {
+ scale = sub(15, q_fx_exp);
+ FOR (i = 0; i < decoder->frame_length; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(x_fx_ip[i], scale));
+#else
+ ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(L_deposit_h(x_fx[i]), scale));
+#endif
+ move16();
+ }
+ }
+ ELSE
+ {
+ FOR (i = 0; i < decoder->frame_length; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(x_fx_ip[i], offset), scale);
+#else
+ ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(L_deposit_h(x_fx[i]), offset), scale);
+#endif
+ move32();
+ }
+ }
+ }
+#ifdef WMOPS
+ BASOP_sub_end(); /* Output scaling */
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_end(); /* Decoder */
+#endif
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return bfi;
+}
+
+/* num_bytes = 0 -> bad frame */
+LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int num_bytes, void **output, int bits_per_sample, void *scratch,
+ int bfi_ext)
+{
+ int ch = 0, bfi = bfi_ext;
+ LC3PLUS_Error err = LC3PLUS_OK;
+ int fec_num_bytes;
+ int lc3_num_bytes;
+ int lc3_channel_num_bytes;
+ int channel_bfi, out_bfi;
+ Word16 channel_epmr;
+
+ if (bfi == 0)
+ {
+ bfi = !num_bytes;
+ }
+
+ if (decoder->ep_enabled)
+ {
+ decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160;
+
+ if (decoder->combined_channel_coding)
+ {
+ fec_num_bytes = num_bytes;
+
+#ifdef WMOPS
+ BASOP_sub_start("fec_dec");
+#endif
+
+ decoder->error_report =
+ fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &decoder->epmr, decoder->combined_channel_coding,
+ &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc,
+ &decoder->m_fec, scratch);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels));
+
+
+ if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size)
+ {
+ err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes);
+
+ if (err)
+ {
+ bfi = 1;
+ }
+ else
+ {
+ decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes;
+ }
+ }
+
+ bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch);
+ input += decoder->channel_setup[ch]->targetBytes;
+ }
+ }
+ else
+ {
+ decoder->epmr = 12;
+ out_bfi = 0;
+
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels));
+
+#ifdef WMOPS
+ BASOP_sub_start("fec_dec");
+#endif
+
+ channel_bfi = bfi;
+
+ decoder->error_report =
+ fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, decoder->combined_channel_coding,
+ &decoder->n_pccw, &channel_bfi, &decoder->be_bp_left, &decoder->be_bp_right,
+ &decoder->n_pc, &decoder->m_fec, scratch);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ decoder->epmr = MIN(decoder->epmr, channel_epmr);
+
+
+#ifdef ENABLE_PADDING
+ if (channel_bfi != 1)
+ {
+ Word16 padding_len, np_zero;
+
+ if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits,
+ decoder->ep_enabled, &padding_len, &np_zero))
+ {
+ channel_bfi = 1;
+ }
+
+ input = input + np_zero;
+ decoder->n_pc = s_max(decoder->n_pc - (2 * np_zero), 0);
+
+ if (channel_bfi == 2)
+ {
+ if (decoder->be_bp_right < (8 * np_zero))
+ {
+ channel_bfi = 0;
+ decoder->be_bp_left = -1;
+ decoder->be_bp_right = -1;
+ }
+ else
+ {
+ decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero);
+ decoder->be_bp_left = s_max(decoder->be_bp_left - (8 * np_zero), 0);
+ }
+ }
+
+ lc3_num_bytes = lc3_num_bytes - padding_len;
+ }
+#endif
+
+ if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size)
+ {
+ err = update_dec_bitrate(decoder, ch, lc3_num_bytes);
+ if (err)
+ {
+ channel_bfi = 1;
+ }
+ else
+ {
+ decoder->channel_setup[ch]->last_size = lc3_num_bytes;
+ }
+ }
+
+ channel_bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], channel_bfi, scratch);
+
+ out_bfi |= channel_bfi;
+ input += fec_num_bytes;
+ }
+
+ bfi = out_bfi & 1;
+ }
+ }
+ else
+ {
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels));
+
+#ifdef ENABLE_PADDING
+ if (bfi != 1)
+ {
+ Word16 padding_len, np_zero;
+
+ if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits,
+ decoder->ep_enabled, &padding_len, &np_zero))
+ {
+ bfi = 1;
+ }
+
+ lc3_num_bytes = lc3_num_bytes - padding_len;
+ if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES)
+ {
+ bfi = 1; /* mark frame as broken if frame sizeif below the minimum of 20 bytes */
+ }
+ }
+#endif
+
+ if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size)
+ {
+ err = update_dec_bitrate(decoder, ch, lc3_num_bytes);
+ if (err)
+ {
+ bfi = 1;
+ }
+ else
+ {
+ decoder->channel_setup[ch]->last_size = lc3_num_bytes;
+ }
+ }
+
+ bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch);
+ input += decoder->channel_setup[ch]->targetBytes;
+ }
+ }
+
+ return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK;
+}
diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9909ddf213cdf3762a564994f06d5272a97bd7d
--- /dev/null
+++ b/lib_lc3plus/defines.h
@@ -0,0 +1,734 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef DEFINES_H
+#define DEFINES_H
+
+#ifndef DISABLE_HR_MODE
+# define ENABLE_HR_MODE
+#endif
+
+#ifdef ENABLE_HR_MODE
+# define MAX_BW_HR 960
+#endif
+
+#ifdef ENABLE_HR_MODE
+# define extractW16(a) extract_h(a)
+#else
+# define extractW16(a) (a)
+#endif
+
+#define MAX_BR 320000 /* 400 * 800 */
+
+/* FUNCTION MACROS */
+/* NB, divisions in some of these MACROs, use mainly for initial setup, do not use in loops */
+#define CEILING(x, y) (((x) + (y)-1) / (y))
+
+#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 */
+#ifdef ENABLE_HR_MODE
+# define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */
+#else
+# define FS2FS_IDX(x) (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 */
+#endif
+
+#define UNUSED(x) (void)(x) /* silence unused parameter warning */
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define STATIC_ASSERTS(cond, s) typedef char assert_##s[(cond) ? 1 : -1]
+#define STATIC_ASSERTI(cond, i) STATIC_ASSERTS(cond, i)
+#define STATIC_ASSERT(cond) STATIC_ASSERTI(cond, __LINE__)
+#define TRACE(x) PRINTF("%s:%i %s = %i\n", __FILE__, __LINE__, #x, (int)(x))
+
+/* For dynamic memory calculations */
+#define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs))
+
+#define DYN_MAX_LEN(fs) (CODEC_FS(fs) / 100)
+#define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */
+#define DYN_MAX_LPROT(fs) ((512 * (CODEC_FS(fs) / 100)) / 320)
+
+#define DYN_MAX_PLOCS(fs) (DYN_MAX_LPROT(fs) / 4 + 1)
+#define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480))
+
+#define MAX_PITCH_FS(fs) (CEILING((MAX_PITCH_12K8 * CODEC_FS(fs)), (12800)))
+
+/* get the maximum buffer size assuming 10 ms framing */
+/* MAX_PITCH was previously always the highest fs in the current SUBSET , i.e. typically 48 kHz */
+/* now fs(from incoming wav file) adaptive MAX_PITCH_FS(fs) is used instead */
+#define DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs) \
+ (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs)) /* CLASSIFIER PCM memory requirement */
+#define DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs) \
+ ((M + 1) + MAX_PITCH_FS(fs) + (DYN_MAX_LEN(fs) / 2)) /* TDC filtering PCM memory requirement */
+
+#ifdef ENABLE_HR_MODE
+# define DYN_MAX_LEN_PCM_PLC(fs) (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs))
+#else
+# define DYN_MAX_LEN_PCM_PLC(fs) MAX(DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs), DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs))
+#endif
+
+#define FRAME_MS_BLOCK 25
+
+/* OPTIONS */
+#define ENABLE_2_5MS_MODE
+#define ENABLE_5MS_MODE
+#define ENABLE_075_DMS_MODE
+#define ENABLE_10_MS_MODE
+#define ENABLE_ADVANCED_PLC
+#define ENABLE_ADVANCED_PLC_DEFAULT
+#define ENABLE_BW_CONTROLLER
+#define ENABLE_ERROR_PROTECTION
+#define ENABLE_RFRAME
+#define ENABLE_PC
+#define ENABLE_PLC
+#define ENABLE_PADDING
+/* flags */
+#define ENABLE_BANDWIDTH_FLAG
+#define ENABLE_RBANDWIDTH_FLAG
+#define ENABLE_EP_MODE_FLAG
+#define ENABLE_FRAME_MS_FLAG
+
+#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */
+#define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */
+#define CR8_F_ADAPT_MDCT_DCT_PRECISION
+#define CR8_G_ADD_75MS
+
+
+#define CR9_B_FIX_MDCT_OVERFLOW /* Fix overflow */
+#define CR9_C_FIX_DCT2_OVERFLOW /* Fix overflow */
+
+#define CR9_F_PITCH_WIN_LEN_FIX /* Increase window length for pitch calculation */
+#define CR9_G_IMPROVE_TDC /* summarize G,H,J,L,N */
+#ifdef CR9_G_IMPROVE_TDC
+# define CR9_G_PLC_NS_TDC_FIX /* Always use TDC if pitch > 0 */
+# define CR9_H_REMOVE_SWITCH_TO_PLC_NS
+# define CR9_J_SLOW_TDC_FADEOUT
+# define CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+# ifdef ENABLE_HR_MODE
+# define CR10_A_ATTENUATION_CURVE_SELECTOR
+# ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+# define CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+# endif
+# endif
+#endif /* CR9_G_IMPROVE_TDC */
+#define CR9_I_INC_TDC_FADEOUT_LEN
+#define CR9_K_REDUCE_NORM_CORR_TH
+#define CR9_M_FIX_DIV_ZERO
+
+#ifndef NO_POST_REL_CHANGES
+/* Post-release non-bitexact changes */
+
+#define CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC
+
+#endif /* NO_POST_REL_CHANGES Post-release changes */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+# ifdef CR9_K_REDUCE_NORM_CORR_TH
+# define THRESH_100_DMS_TDC_CNT 9
+# define THRESH_100_DMS_NS_CNT 7
+# define THRESH_100_DMS_TDC_NS_CNT 73
+# define THRESH_075_DMS_TDC_CNT 7
+# define THRESH_075_DMS_NS_CNT 7
+# define THRESH_075_DMS_TDC_NS_CNT 87
+# define THRESH_050_DMS_TDC_CNT 22
+# define THRESH_050_DMS_NS_CNT 15
+# define THRESH_050_DMS_TDC_NS_CNT 141
+# define THRESH_025_DMS_TDC_CNT 20
+# define THRESH_025_DMS_NS_CNT 21
+# define THRESH_025_DMS_TDC_NS_CNT 278
+# else
+# define THRESH_100_DMS_TDC_CNT 3
+# define THRESH_100_DMS_NS_CNT 35
+# define THRESH_100_DMS_TDC_NS_CNT 114
+# define THRESH_075_DMS_TDC_CNT 6
+# define THRESH_075_DMS_NS_CNT 37
+# define THRESH_075_DMS_TDC_NS_CNT 130
+# define THRESH_050_DMS_TDC_CNT 12
+# define THRESH_050_DMS_NS_CNT 55
+# define THRESH_050_DMS_TDC_NS_CNT 227
+# define THRESH_025_DMS_TDC_CNT 10
+# define THRESH_025_DMS_NS_CNT 138
+# define THRESH_025_DMS_TDC_NS_CNT 431
+# endif
+# else
+# define FAC1_FADEOUT 6710886 /* 0.2 * 2^25 */
+# define SHIFT1_FADEOUT 25-15 /* 25 - 16 */
+# define FAC2_FADEOUT 50331648 /* 1.5 * 2^25 */
+# define SHIFT2_FADEOUT 25-15 /* 25 - 16 */
+# define FAC3_FADEOUT 58720256 /* 1.75 * 2^25 */
+# define SHIFT3_FADEOUT 25-15 /* 25 - 16 */
+# endif
+# define PLC_LONGTERM_ANALYSIS_MS 200 /* Nominal analysis window 2000 ms */
+# define PLC_LONGTERM_ANALYSIS_STARTUP_FILL (Word16)(0.5*32768.0) /* 16384/32768 == 0.5 required buffer fill amount, set to 0.0 to not require any fill at all */
+#endif /* CR8_A_PLC_FADEOUT_TUNING */
+
+#define REL_PITCH_THRESH 11796
+
+# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */
+# ifdef SUBSET_NB
+# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */
+# endif
+# ifdef SUBSET_WB
+# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */
+# endif
+# ifdef SUBSET_SSWB
+# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */
+# endif
+
+/* G192 bitstream writing/reading */
+#define G192_GOOD_FRAME 0x6B21
+#define G192_BAD_FRAME 0x6B20
+#define G192_REDUNDANCY_FRAME 0x6B22
+#define G192_ZERO 0x007F
+#define G192_ONE 0x0081
+#define READ_G192FER /* allow C executable to also read G192 formatted FER files */
+
+#ifdef DEBUG
+#ifdef READ_G192FER
+# define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */
+#endif
+#endif
+
+
+// #define DYNMEM_COUNT
+#define STAMEM_COUNT
+
+
+/*
+do not change __forceinline for mex compilation using gcc6.3.0 or larger
+ gcc630 supported by MATLAB 2018b, via Mingw "app"
+ */
+#ifdef __GNUC__
+# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#else
+# define GCC_VERSION 0
+#endif
+
+/* Define __forceinline as empty if ARM not activated to avoid any errors */
+#undef __forceinline
+/* The above undef is needed to compile using make_mex.m without the following warning in Matlab for windows */
+#define __forceinline
+
+/* SUBSETS */
+#if !(defined(SUBSET_NB) || defined(SUBSET_WB) || defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) || defined(SUBSET_UB))
+# define SUBSET_NB
+# define SUBSET_WB
+# define SUBSET_SSWB
+# define SUBSET_SWB
+# define SUBSET_FB
+# ifdef ENABLE_HR_MODE
+# define SUBSET_UB
+# endif
+#endif
+
+# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */
+# define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */
+# define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */
+# define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */
+# ifdef SUBSET_NB
+# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */
+# endif
+# ifdef SUBSET_WB
+# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */
+# endif
+# ifdef SUBSET_SSWB
+# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */
+# endif
+
+#ifdef CR8_G_ADD_75MS
+# define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800
+# define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800
+# define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */
+# define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */
+# define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */
+# define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */
+# define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */
+
+# define NOISEFILLWIDTH_7_5MS 2
+# define NOISEFILLSTART_7_5MS 18
+#endif
+
+#define PACK_RESBITS
+
+/* FRAME/BUFFER */
+#ifdef SUBSET_UB
+# define MAX_LEN 960 /* = 10ms at 96kHz */
+#elif defined SUBSET_FB
+# define MAX_LEN 480 /* = 10ms at 48kHz */
+#elif defined(SUBSET_SWB)
+# define MAX_LEN 320 /* = 10ms at 32kHz */
+#elif defined(SUBSET_SSWB)
+# define MAX_LEN 240 /* = 10ms at 24kHz */
+#elif defined(SUBSET_WB)
+# define MAX_LEN 160 /* = 10ms at 16kHz */
+#elif defined(SUBSET_NB)
+# define MAX_LEN 80 /* = 10ms at 8kHz */
+#endif
+
+#ifdef ENABLE_HR_MODE
+# define ENABLE_FFT_RESCALE
+# define ENABLE_FFT_30X16
+# define ENABLE_DCTIV_RESCALE
+
+# define EXT_RES_ITER_MAX 20
+# define MAX_RESBITS 5000
+# define HR_MODE_SCRATCH_SIZE 60
+#else /* ENABLE_HR_MODE */
+# define MAX_RESBITS MAX_LEN
+#endif /* ENABLE_HR_MODE */
+
+/* BW Cutoff-Detection */
+#define MAX_BW_BANDS_NUMBER 5
+
+#ifdef ENABLE_HR_MODE
+# define RESBITS_PACK_SHIFT 3
+# define RESBITS_PACK_N (1<<(RESBITS_PACK_SHIFT))
+# define RESBITS_PACK_MASK (RESBITS_PACK_N - 1)
+# define MAX_RESBITS_LEN ((MAX_RESBITS + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT)
+# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4)
+#else /* ENABLE_HR_MODE */
+# define MAX_RESBITS_LEN (MAX_RESBITS)
+# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4)
+#endif /* ENABLE_HR_MODE */
+
+#define MAX_CHANNELS 2
+#define MIN_NBYTES 20 /* 100dms: 16 kbps at !=44.1kHz, 14.7kbps at 44.1kHz
+ 50dms: 32 kbps at !=44.1kHz, 29.4kbps at 44.1kHz
+ 25dms: 64 kbps at !=44.1kHz, 58.8kbps at 44.1kHz */
+#define MAX_NBYTES_025 100 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */
+#define MAX_NBYTES_050 200 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */
+#define MAX_NBYTES_075 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */
+#define MAX_NBYTES_100 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */
+#ifdef ENABLE_HR_MODE
+# define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200
+# define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200
+# define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600
+# define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600
+# define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800
+# define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800
+# define MAX_NBYTES_RED_HR 625 /* From table 5.2 */
+# define BYTESBUFSIZE (MAX_NBYTES_RED_HR * LC3PLUS_MAX_CHANNELS)
+#else
+# define BYTESBUFSIZE (MAX_NBYTES_100 * LC3PLUS_MAX_CHANNELS)
+#endif
+#define MAX_BW_BIN 400
+#define FEC_SLOT_BYTES_MIN 40
+# define FEC_SLOT_BYTES_MAX 400
+#if MAX_BW_BIN > MAX_LEN
+# define MAX_BW MAX_LEN
+#else
+# define MAX_BW MAX_BW_BIN
+#endif
+
+#define NUM_OFFSETS 7
+#define NUM_SAMP_FREQ 6
+
+/* SCF */
+#define M 16 /* LPC_ORDER */
+#define MAX_BANDS_NUMBER 64
+#define MAX_BANDS_NUMBER_PLC 80
+#define PVQ_MAX_VEC_SIZE M
+#define KMAX_FX 10 /* N=10 */
+#define K_OUTL_FAR 6
+#define MPVQ_SZ_OUTL_FAR (1549824U >> 1)
+#define TOTBITS_SHAPE OUTL_FAR(1.0 + 19.5637)
+#define SQRT_EN_MAX_FX 64 /* table size, for fast inv_sqrt */
+#define N_SETA 10
+#define N_SETB (PVQ_MAX_VEC_SIZE - N_SETA)
+
+#define SNS_DAMPING 27853 /* 0.85 in Q15 */
+#ifdef ENABLE_HR_MODE
+# define SNS_DAMPING_HRMODE 19661 /* 0.6 in Q15 */
+# define SNS_DAMPING_HRMODE_UB_10MS 6881 /* 0.21 in Q15 */
+# define SNS_DAMPING_HRMODE_UB_7_5MS 5898 /* 0.18 in Q15 */
+# define SNS_DAMPING_HRMODE_UB_5MS 4915 /* 0.15 in Q15 */
+# define SNS_DAMPING_HRMODE_UB_2_5MS 4915 /* 0.15 in Q15 */
+#endif
+
+/* PVQ VQ setup */
+#define VQMODES26 \
+ ((0 << 4) + (1 << 3) + (1 << 2) + (1 << 1) + \
+ (1 << 0)) /* select all shapes, including extended lf, and new far \
+ shape for MODE26, add extreme far mode not enabled */
+#define SCF_STAGE1_MAX_BITS (5 + 5) /* typically only (5+5) used */
+#define SCF_STAGE1_NBCDKENTRIES 32
+#define SCF_STAGE2_MAX_GAIN_BITS 2
+#define SCF_STAGE2_NB_MODE_BITS 1
+#define SCF_STAGE2_MAX_NB_SHAPES 3
+#define SCF_MAX_PARAM 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), submode-LSB */
+#define SCF_MAX_PARAM_ST2 (SCF_MAX_PARAM - 2)
+#define N_SCF_SHAPES_ST2 4
+#define N_SCF_SHAPE_SETUPS 1
+
+/* ARITHMETIC ENCODER */
+#define NBITS_CONTEXT 8
+#define NBITS_RATEQ 2
+#define A_THRES_SHIFT 2
+#define A_THRES (1 << A_THRES_SHIFT)
+#define VAL_ESC 16
+#define SYM_BITS_Q 11
+
+/* RESIDUAL CODING */
+#define NPRM_RESQ MAX_LEN
+
+/* NOISE FILLING */
+#define NOISEFILLWIDTH 3
+#define NOISEFILLSTART 24
+#define NOISEFILLWIDTH_5MS 1
+#define NOISEFILLSTART_5MS 12
+#define NOISEFILLWIDTH_2_5MS 1
+#define NOISEFILLSTART_2_5MS 6
+
+/* MDCT */
+#ifdef ENABLE_HR_MODE
+# define TWIDDLE ((Word32)0x5a82799a)
+#else
+# define TWIDDLE WORD322WORD16(0x5a82799a)
+#endif
+#define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480))
+
+/* TNS */
+#define TNS_NUMFILTERS_MAX 2
+#define TNS_COEF_RES 17
+#define INDEX_SHIFT 8
+#define NSUBDIV 3
+#define MAXLAG 8
+
+/* OLPA/LTPF */
+#define LEN_12K8 128
+#define LEN_6K4 64
+#define MIN_PITCH_6K4 17
+#define MAX_PITCH_6K4 114
+#define RANGE_PITCH_6K4 98
+#define MIN_PITCH_12K8 32
+#define MAX_PITCH_12K8 228
+#define RES2_PITCH_12K8 157
+#define RES4_PITCH_12K8 127
+#define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4)
+#define M_LTPF 24
+#define LTPF_MEM_X_LEN (MAX_LEN + MAX_LEN / 40 - 2)
+#define LTPF_MEM_Y_LEN (MAX_LEN + CEILING(MAX_PITCH_12K8 * MAX_LEN, 128) + (MAX_LEN / 80))
+
+/* PLC */
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+# define PLC_FADEOUT_TYPE_1_IN_MS 200
+#endif
+#define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */
+
+# ifdef CR8_A_PLC_FADEOUT_TUNING
+ /* table settings */
+# define PLC2_FADEOUT_IN_MS_MIN 30 /* table min */
+# define PLC2_FADEOUT_IN_MS_MAX 140 /* table max */
+# define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fade tables */
+
+/* current settings */
+# define PLC2_FADEOUT_LONG_IN_MS 120
+# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original constants for PLC2
+ -1 uses TDC::PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation
+ 30..140 will use a separate settings for PLC2 fadeout
+ 30: P800 short fade optimization
+ 120: Mushra optimized fade */
+#else
+# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original fixed values for PLC2
+ -1 uses PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation
+ 30..100 uses separate setting for PLC2 */
+#endif
+
+
+
+#define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */
+#define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */
+#define PLC34_ATTEN_FAC_100_FX 0x4000 /* attenuation factor for NS and TDC @ 10 ms (0.5000)*/
+#define PLC34_ATTEN_FAC_050_FX 0x5A83 /* attenuation factor for NS and TDC @ 5.0 ms (0.7071)*/
+#define PLC34_ATTEN_FAC_025_FX 0x6BA3 /* attenuation factor for NS and TDC @ 2.5 ms (0.8409)*/
+#ifdef CR8_G_ADD_75MS
+#define PLC34_ATTEN_FAC_075_FX 0x4C1C /* attenuation factor for NS and TDC @ 7.5 ms (0.5946) */
+#endif
+#define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */
+
+#define MAX_PITCH_8K (CEILING((MAX_PITCH_12K8 * 8000), (12800))) /*NB was a risky MACRO at 0.5 border !!, */
+#define MAX_PITCH_16K ((MAX_PITCH_12K8 * 16000) / (12800)) /* exact integer */
+#define MAX_PITCH_24K \
+ (CEILING((MAX_PITCH_12K8 * 24000), (12800))) /* was a risky MACRO truncation at 0.5 border !! , */
+#define MAX_PITCH_32K ((MAX_PITCH_12K8 * 32000) / (12800)) /* exact integer */
+#define MAX_PITCH_48K ((MAX_PITCH_12K8 * 48000) / (12800)) /* exact integer */
+
+#ifdef ENABLE_HR_MODE
+# define MAX_PITCH_96K ((MAX_PITCH_12K8 * 96000) / (12800)) /* exact integer */
+#endif
+
+#ifdef ENABLE_HR_MODE
+# define MAX_PITCH MAX_PITCH_96K
+#elif defined(SUBSET_FB)
+# define MAX_PITCH MAX_PITCH_48K
+#elif defined(SUBSET_SWB)
+# define MAX_PITCH MAX_PITCH_32K
+#elif defined(SUBSET_SSWB)
+# define MAX_PITCH MAX_PITCH_24K
+#elif defined(SUBSET_WB)
+# define MAX_PITCH MAX_PITCH_16K
+#elif defined(SUBSET_NB)
+# define MAX_PITCH MAX_PITCH_8K
+#endif
+
+
+/* macri MAX_LEN_PCM_PLC is used for WC memory size checking
+ DYN_MAX_LEN_PCM_PLC(fs) is used by static memory buffers
+ */
+#define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN)
+
+#define TDC_L_FIR_HP 11
+#define TDC_L_FIR_LP 11
+
+#define BASE_LPROT 512 /* BASE Lprot set to 512 for 32 kHz sampling */
+
+#define LPROT48K (BASE_LPROT * 48 / 32) /* Fs based Lprot */
+#define LPROT40K (BASE_LPROT * 40 / 32) /* For Fs == 48000 only use 0 - 20000 Hz in 8 bands */
+#define LPROT32K BASE_LPROT
+#define LPROT24K (BASE_LPROT * 24 / 32)
+#define LPROT16K (BASE_LPROT * 16 / 32)
+#define LPROT8K (BASE_LPROT * 8 / 32)
+
+/* #define PHECU_XFP_LA 1 */ /* Original soluiton xfp generated with 1ms look ahead into MDCT memory
+ ctrl.PhECU.LA = 0.001 * ctrl.fs; */
+/* #define PHECU_XFP_LA 4 */ /* Option with some lookahead 1/4 ms look ahead into MDCT memory
+ ctrl.PhECU.LA = 0.001 * ctrl.fs / 4; */
+#define PHECU_XFP_LA \
+ 0 /* Option without lookahead 0 ms look ahead into MDCT memory \
+ ctrl.PhECU.LA = 0; */
+
+#if (PHECU_XFP_LA == 0)
+
+# define PHECU_LA_48K 0 /* 0 ms */
+# define PHECU_LA_32K 0 /* 0 ms */
+# define PHECU_LA_24K 0 /* 0 ms */
+# define PHECU_LA_16K 0 /* 0 ms */
+# define PHECU_LA_8K 0 /* 0 ms */
+
+# define MAX_PHECU_LA (0)
+
+#else
+# if (PHECU_XFP_LA == 4)
+
+# define PHECU_LA_48K (48 / 4) /* 0.25 ms */
+# define PHECU_LA_32K (32 / 4) /* 0.25 ms */
+# define PHECU_LA_24K (24 / 4) /* 0.25 ms */
+# define PHECU_LA_16K (16 / 4) /* 0.25 ms */
+# define PHECU_LA_8K (8 / 4) /* 0.25 ms */
+
+# define MAX_PHECU_LA (MAX_LEN / 10 / 4)
+
+# else
+
+# define PHECU_LA_48K 48 /* 1 ms */
+# define PHECU_LA_32K 32 /* 1 ms */
+# define PHECU_LA_24K 24 /* 1 ms */
+# define PHECU_LA_16K 16 /* 1 ms */
+# define PHECU_LA_8K 8 /* 1 ms */
+
+# define MAX_PHECU_LA (MAX_LEN / 10)
+
+# endif
+#endif
+
+
+/* (PHECU_LA_48K == 0) */
+
+#define COPY_LEN_8K 16
+#define COPY_LEN_16K 32
+#define COPY_LEN_24K 48
+#define COPY_LEN_32K 64
+#define COPY_LEN_48K 96
+
+#define OLA_LEN_8K 14
+#define OLA_LEN_16K 28
+#define OLA_LEN_24K 42
+#define OLA_LEN_32K 56
+#define OLA_LEN_48K 84
+
+#define LPROT48K_RED LPROT40K /* limit peak searched part of spectrum for FB */
+#define LPROT32K_RED LPROT32K /* limit peak searched part of spectrum for SWB */
+#define LPROT24K_RED LPROT24K /* limit peak searched part of spectrum for HQ */
+#define LPROT16K_RED LPROT16K /* limit peak searched part of spectrum for SQ */
+#define LPROT8K_RED LPROT8K /* limit peak searched part of spectrum for NB */
+
+#define INV_LPROT48K_Q22 5461 /* round(2^22/LPROT48K) , 1/6 */
+#define INV_LPROT32K_Q22 8192 /* round(2^22/LPROT32K) , 1/4 */
+#define INV_LPROT24K_Q22 10923 /* round(2^22/LPROT24K) , 1/3 */
+#define INV_LPROT16K_Q22 16384 /* round(2^22/LPROT16K) , 1/2 */
+#define INV_LPROT8K_Q22 32767 /* round(2^22/LPROT8K) , 1/1 */
+
+#define LGW48K 8 /* 8 bands defined , but may the same frequency groups as for SWB(32k) */
+#define LGW32K 7
+#define LGW24K 6
+#define LGW16K 5
+#define LGW8K 4
+
+#define MAX_LGW 9 /* LGW48K + 1 !! */
+
+#define UNINIT_OR_UNSAFE_OOLD_SENTINEL -32768
+#define LTOT_INIT_FLAG -32768
+#define LTOT_MIN_MAN 1 /* lowest possible energy value */
+#define LTOT_MIN_EXP -61 /* L_tot= LTOT_MIN_MAN*2^(LTOT_MIN_EXP-31) */
+#define GRP_SHAPE_INIT 0 /* Q15 */
+
+#define TRANA_TIME 4 /* Transient analysis length in ms */
+#define LTRANA48K (48000 * TRANA_TIME / 1000)
+#define LTRANA32K (32000 * TRANA_TIME / 1000)
+#define LTRANA24K (24000 * TRANA_TIME / 1000)
+#define LTRANA16K (16000 * TRANA_TIME / 1000)
+#define LTRANA8K (8000 * TRANA_TIME / 1000)
+
+#define MAX_PLOCS ((MAX_LPROT / 4) + 1) /* maximum number of spectral peaks to be searched */
+#define QUOT_LPR_LTR 4
+
+#define BETA_MUTE_FAC_INI 16384 /* Q15, initial noise attenuation factor */
+
+#define OFF_FRAMES_LIMIT 30 /* Hard limit to a maximum of 300ms of burst decay frames */
+
+#define Lprot_hamm_len2_48k (3 * 48)
+#define Lprot_hamm_len2_32k (3 * 32)
+#define Lprot_hamm_len2_24k (3 * 24)
+#define Lprot_hamm_len2_16k (3 * 16)
+#define Lprot_hamm_len2_8k (3 * 8)
+
+#define FRAME_TIME 10 /* Frame length in ms */
+
+#define L_FRAME48K (48000 * FRAME_TIME / 1000)
+#define L_FRAME32K (32000 * FRAME_TIME / 1000)
+#define L_FRAME24K (24000 * FRAME_TIME / 1000)
+#define L_FRAME16K (16000 * FRAME_TIME / 1000)
+#define L_FRAME8K (8000 * FRAME_TIME / 1000)
+
+#ifdef DISABLE_PLC
+# define MAX_LTRANA 0
+# define MAX_LPROT LPROT48K
+# define MAX_L_FRAME L_FRAME48K
+# define MAX_LPROT_RED LPROT48K_RED
+#else
+
+# ifdef SUBSET_UB
+# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */
+# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA48K
+# define MAX_L_FRAME L_FRAME48K
+# elif defined(SUBSET_FB)
+# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */
+# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA48K
+# define MAX_L_FRAME L_FRAME48K
+# elif defined(SUBSET_SWB)
+# define MAX_LPROT LPROT32K
+# define MAX_LPROT_RED LPROT32K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA32K
+# define MAX_L_FRAME L_FRAME32K
+# elif defined(SUBSET_SSWB)
+# define MAX_LPROT LPROT24K
+# define MAX_LPROT_RED LPROT24K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA24K
+# define MAX_L_FRAME L_FRAME24K
+# elif defined(SUBSET_WB)
+# define MAX_LPROT LPROT16K
+# define MAX_LPROT_RED LPROT16K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA16K
+# define MAX_L_FRAME L_FRAME16K
+# elif defined(SUBSET_NB)
+# define MAX_LPROT LPROT8K
+# define MAX_LPROT_RED LPROT8K_RED /* stack alloc peak searched part */
+# define MAX_LTRANA LTRANA8K
+# define MAX_L_FRAME L_FRAME8K
+# endif
+
+#endif /* #ifdef DISABLE_PLC */
+
+#define INV_L_FRAME48K_Q15 32768 / L_FRAME48K
+#define INV_L_FRAME32K_Q15 32768 / L_FRAME32K
+#define INV_L_FRAME24K_Q15 32768 / L_FRAME24K
+#define INV_L_FRAME16K_Q15 32768 / L_FRAME16K
+#define INV_L_FRAME8K_Q15 32768 / L_FRAME8K
+
+#define MDCT_MEM_LEN_48 (L_FRAME48K - ((180 * L_FRAME48K) / 480))
+
+#define R1_48 690
+#define R2_48 420
+#define R1_16 230
+#define R2_16 140
+#define R1_25 368
+#define R2_25 224
+
+#define MAX_LEN_PCM_PLC_TOT (MAX_LEN_PCM_PLC) /* TDC_pcm_buff */
+#define MAX_WIN_PRE_TDA (0) /* not in RAM any longer , now stored in ROM only as PhECU_wins[fs_idx][1] */
+
+#define MAX_PLCMETH 1
+
+/* Scratch buffer defines */
+#define scratchBuffer_ACTIVE
+#ifdef ENABLE_HR_MODE
+# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 4 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN)
+# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN + 8 * 60 + MAX_LEN)
+#else
+# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN)
+# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN)
+#endif
+
+#define SCRATCH_BUF_LEN_ENC_TOT (SCRATCH_BUF_LEN_ENC + SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH)
+
+#ifdef ENABLE_HR_MODE
+# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN + 32 + 32 + 4 * MAX_LEN + 32 + 128 + 128)
+#else
+# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + 2 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 32 + 128 + 128)
+#endif
+#define SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH (2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME)
+#ifdef ENABLE_HR_MODE
+# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + (4 * HR_MODE_SCRATCH_SIZE) + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH)
+#else
+# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH)
+#endif
+
+#define ADVACED_PLC_SIZE \
+ (sizeof(AplcSetup) + (4 + 2) * MAX_PLOCS + 2 * MAX_LEN_PCM_PLC_TOT + 0 * MAX_LPROT + 2 * MDCT_MEM_LEN_MAX + \
+ 2 * MAX_WIN_PRE_TDA)
+/* ERI : Correct this sum after ROM/RAM , joint RAM optimizations */
+
+
+#define ENC_MAX_SIZE (sizeof(LC3PLUS_Enc) + MAX_CHANNELS * (sizeof(EncSetup) + 6 * MDCT_MEM_LEN_MAX))
+#define DEC_MAX_SIZE \
+ (sizeof(LC3PLUS_Dec) + MAX_CHANNELS * (sizeof(DecSetup) + ADVACED_PLC_SIZE + 2 * LTPF_MEM_X_LEN + 2 * LTPF_MEM_Y_LEN + \
+ 2 * MDCT_MEM_LEN_MAX + 2 * MAX_BW))
+
+#if (defined(_M_ARM) || defined(__CC_ARM) || defined(__TMS470__) || defined(__arm__) || defined(__aarch64__)) && \
+ (defined(__TARGET_FEATURE_NEON) || defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__ARM_AARCH64_NEON__))
+# define ALIGNMENT_DEFAULT 16
+#elif defined(__bfin__)
+# define ALIGNMENT_DEFAULT 4
+#else
+# define ALIGNMENT_DEFAULT 8
+#endif
+
+/* RAM_ALIGN keyword causes memory alignment of global variables. */
+#if defined(__GNUC__)
+# define RAM_ALIGN __attribute__((aligned(ALIGNMENT_DEFAULT)))
+#elif defined(__CC_ARM)
+# define RAM_ALIGN __align(ALIGNMENT_DEFAULT)
+#elif defined(__ANALOG_EXTENSIONS__)
+# define RAM_ALIGN
+# pragma pack(ALIGNMENT_DEFAULT)
+#elif defined(_MSC_VER)
+# define RAM_ALIGN __declspec(align(ALIGNMENT_DEFAULT))
+#else
+# define RAM_ALIGN
+#endif
+
+#define scratchAlign(ptr, offset) (void *)(((uintptr_t)(ptr) + (offset) + 0x3) & ~0x3)
+#define ALIGN_BUFFER_STRUCT
+
+
+/* some configurations leave empty translation units. */
+extern int fix_empty_translation_unit_warning;
+
+#endif
diff --git a/lib_lc3plus/detect_cutoff_warped_fx.c b/lib_lc3plus/detect_cutoff_warped_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6ef2547290b3baa2f4f4984b97b74c249707bb0
--- /dev/null
+++ b/lib_lc3plus/detect_cutoff_warped_fx.c
@@ -0,0 +1,124 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "rom_basop_util.h"
+
+void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms)
+{
+
+ Dyn_Mem_Deluxe_In(
+ Counter iBand;
+ Word32 d2_fx_sum;
+ Word32 d2_fx_mean;
+ Word32 delta_energy;
+ Word16 d2_fx_sum_exp;
+ Word16 d2_fx_mean_exp;
+ Word16 nrg_below_thresh;
+ Word16 counter;
+ Word16 brickwall;
+ Word16 stop;
+ Word16 brickwall_dist;
+ const Word16 *warp_idx_start, *warp_idx_stop, *bw_brickwall_dist;
+ );
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1]; move16();
+ warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1]; move16();
+ bw_brickwall_dist = BW_brickwall_dist_2_5ms;
+ BREAK;
+ case 50:
+ warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1]; move16();
+ warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; move16();
+ bw_brickwall_dist = BW_brickwall_dist_5ms;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; move16();
+ warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; move16();
+ bw_brickwall_dist = BW_brickwall_dist_7_5ms;
+ BREAK;
+#endif
+ default: /* 100 */
+ warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; move16();
+ warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; move16();
+ bw_brickwall_dist = BW_brickwall_dist;
+ BREAK;
+ }
+
+ counter = fs_idx;
+ DO
+ {
+
+ /* counter is 0...num_idxs-1 */
+ counter = sub(counter, 1);
+
+ /* always code the lowest band (NB), skip check against threshold if counter == -1 */
+ IF (counter < 0)
+ {
+ BREAK;
+ }
+
+ d2_fx_mean = 0; move32();
+ d2_fx_mean_exp = 0; move16();
+
+ iBand = warp_idx_start[counter]; move16();
+ d2_fx_sum = d2_fx[iBand]; move32();
+ d2_fx_sum_exp = d2_fx_exp; move16();
+
+ iBand++;
+ FOR (; iBand <= warp_idx_stop[counter]; iBand++)
+ {
+ d2_fx_sum = BASOP_Util_Add_Mant32Exp_lc3plus(d2_fx[iBand], d2_fx_exp, d2_fx_sum, d2_fx_sum_exp, &d2_fx_sum_exp);
+ }
+ /* Energy-sum */
+ d2_fx_mean = Mpy_32_16_lc3plus(d2_fx_sum, InvIntTable[add(sub(warp_idx_stop[counter], warp_idx_start[counter]), 1)]);
+ d2_fx_mean_exp = d2_fx_sum_exp; move16();
+
+ /* check if above threshold */
+ nrg_below_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(BW_thresh_quiet[counter], BW_thresh_quiet_exp, d2_fx_mean,
+ d2_fx_mean_exp); /* true if firstNumber > secondNumber */
+ }
+ WHILE (nrg_below_thresh > 0)
+ ;
+
+ *bw_idx = add(1, counter); move16();
+
+ /* addtional check for brickwall characteristic */
+ IF (sub(fs_idx, *bw_idx) > 0)
+ {
+ brickwall = 0; move16();
+ stop = add(warp_idx_start[counter + 1], 1);
+ brickwall_dist = bw_brickwall_dist[counter + 1];
+
+ FOR (iBand = stop; iBand >= sub(stop, brickwall_dist); iBand--)
+ {
+ /* Band(x) > Band(x-3)*Thr */
+ delta_energy =
+ L_sub(Mpy_32_16_lc3plus(d2_fx[iBand - brickwall_dist], BW_thresh_brickwall[counter + 1]), d2_fx[iBand]);
+ if (delta_energy > 0)
+ {
+ brickwall = 1; move16();
+ }
+ IF (brickwall)
+ {
+ BREAK;
+ }
+ }
+ if (brickwall == 0)
+ {
+ *bw_idx = fs_idx;
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/dynmem.c b/lib_lc3plus/dynmem.c
new file mode 100644
index 0000000000000000000000000000000000000000..65e157d0a19674301e84bd729035143ff4f1d153
--- /dev/null
+++ b/lib_lc3plus/dynmem.c
@@ -0,0 +1,288 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+
+/*
+ Tool for dynamic memory estimation
+ Anisse Taleb, November 2003
+
+*/
+
+/* turn off stdlib function warnings in visual studio */
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "dynmem.h"
+
+#define MAX_FUNC_NAME_LENGTH 128
+
+
+
+struct C_Path{
+ char func_name[MAX_FUNC_NAME_LENGTH];
+ long mem_usage;
+ long mem_usage_acc;
+ struct C_Path *next;
+ struct C_Path *parent;
+};
+
+
+typedef struct C_Path C_Path;
+
+static C_Path *Max_Mem_path; /* Snap shot of the maximum memory usage path */
+static C_Path *Head_path;
+static C_Path *Curr_path; /* Current code path */
+
+
+static long Max_mem_usage;
+
+static C_Path *Static_mem_head;
+static C_Path *Static_mem_curr;
+
+/*
+ * initialisation. Must be called at start, sets up all the
+ * structures and resets counters.
+ *
+ * Called externally.
+ */
+
+static void path_free(C_Path * path)
+{
+ C_Path *path_end,*tmp;
+ path_end = path;
+
+ if(path == NULL) return;
+ /* find last node */
+ while(path_end->next != NULL) path_end = path_end->next;
+
+ /* walk back */
+ while(path_end != NULL) {
+ tmp = path_end;
+ path_end = path_end->parent;
+ free(tmp);
+ }
+
+}
+static void path_save(void)
+{
+ C_Path * node;
+ C_Path * node_save;
+ C_Path * previous;
+ /* free the old path */
+ path_free(Max_Mem_path);
+ Max_Mem_path = NULL;
+ /* */
+
+ Max_Mem_path = (C_Path *) malloc(sizeof(C_Path));
+
+ node = Head_path;
+ node_save = Max_Mem_path;
+ previous = NULL;
+ while(node != NULL){
+
+ strcpy(node_save->func_name,node->func_name);
+ node_save->mem_usage = node->mem_usage;
+ node_save->mem_usage_acc = node->mem_usage_acc;
+
+ node_save->parent = previous;
+ node_save->next = NULL;
+
+ if(node->next != NULL) {
+ node_save->next = (C_Path *) malloc(sizeof(C_Path));
+ }
+ node = node->next;
+ previous = node_save;
+ node_save = node_save->next;
+ } while(node != NULL);
+
+}
+
+void P_Dyn_Mem_Init(void)
+{
+
+ /* initialize the path */
+ Head_path = (C_Path *) malloc(sizeof(C_Path));
+ strcpy(Head_path->func_name,"---Top---");
+ Head_path->mem_usage = 0;
+ Head_path->mem_usage_acc = 0; /*memory usage accumulator */
+ Head_path->parent = NULL;
+ Head_path->next = NULL;
+
+ Curr_path = Head_path;
+ /* Initilaize the memory consumptions */
+ Max_mem_usage = 0;
+ Max_Mem_path = NULL;
+}
+
+void P_Dyn_Mem_In(const char *func_name,
+ long mem_usage)
+{
+#ifdef DEBUG_DYNMEM
+ printf( "Entering: %s\n", func_name );
+#endif
+
+ /* Enter a new function, push on the stack */
+ if(Curr_path->next != NULL) {
+ fprintf(stderr,"\n Something went wrong !!");
+ exit(0);
+
+ }
+ Curr_path->next = (C_Path*) malloc (sizeof(C_Path));
+
+ if(Curr_path->next == NULL) {
+ fprintf(stderr,"\n Can't allocate memory");
+ exit(0);
+ }
+
+ Curr_path->next->parent = Curr_path;
+ Curr_path = Curr_path->next;
+ Curr_path->next = NULL;
+ /* save function name */
+ strcpy(Curr_path->func_name,func_name);
+ /* save memory usage */
+ Curr_path->mem_usage = mem_usage;
+ /* update memory usage accumulator */
+ Curr_path->mem_usage_acc = Curr_path->parent->mem_usage_acc + mem_usage;
+}
+
+/* Add memory size to current function */
+void P_Dyn_Mem_Add(long mem_usage)
+{
+#ifdef DEBUG_DYNMEM
+ printf( "Staying in: %s\n", Curr_path->func_name);
+#endif
+
+ /* Staying in the current function, nothing to push */
+
+ /* save memory usage */
+ Curr_path->mem_usage = Curr_path->mem_usage + mem_usage;
+ /* update memory usage accumulator */
+ Curr_path->mem_usage_acc = Curr_path->mem_usage_acc + mem_usage;
+}
+
+
+/* before any return */
+
+void P_Dyn_Mem_Out(void)
+{
+ C_Path *tmp;
+ if(Curr_path->mem_usage_acc > Max_mem_usage) {
+ /* set new memory usage record */
+ Max_mem_usage = Curr_path->mem_usage_acc;
+ /* save snap shot */
+ path_save();
+ }
+
+#ifdef DEBUG_DYNMEM
+ printf( "Exiting: %s\n", Curr_path->func_name );
+#endif
+
+ /* delete last node */
+ tmp = Curr_path;
+
+ Curr_path = Curr_path->parent;
+ Curr_path->next = NULL;
+ free(tmp);
+}
+
+
+/* Write data and exit */
+
+void P_Dyn_Mem_Exit(void)
+{
+ /*FILE *f_mem_statistics;*/
+ C_Path *node;
+ /*f_mem_statistics = fopen("mem_stat.txt","wt");
+ fprintf(f_mem_statistics,"\n Maximum dynamic memory usage = %ld b, %ld kW \n Critical Memory Usage Path", Max_mem_usage, Max_mem_usage/(1000*2));*/
+ /* fprintf(stderr,"\n Maximum dynamic memory usage = %ld kWords (%ld bytes)\n Critical Memory Usage Path", Max_mem_usage/(1000*2),Max_mem_usage); */
+ fprintf(stderr,"\n Maximum dynamic memory usage = %.2f kWords (%ld bytes)\n Critical Memory Usage Path", (ceil((float)Max_mem_usage/20.f)/100.f), Max_mem_usage);
+
+ node = Max_Mem_path;
+ while (node != NULL) {
+ /*fprintf(f_mem_statistics,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage);*/
+ fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage);
+ node=node->next;
+ }
+
+ /*fclose(f_mem_statistics);*/
+ fprintf(stderr,"\n");
+
+#ifdef CTEST_MEASUREMENTS
+ printf("%.3f\n", "dynMem [kWords]", "numeric/float", Max_mem_usage/(1000.0*2));
+#endif
+
+ path_free(Max_Mem_path);
+ path_free(Head_path);
+}
+
+void P_Dyn_Mem_Exit_noprint(void)
+{
+ path_free(Max_Mem_path);
+ path_free(Head_path);
+}
+void P_Sta_Mem_Init(void)
+{
+ /* initialize the head object */
+ Static_mem_head = (C_Path *) malloc(sizeof(C_Path));
+ strcpy(Static_mem_head->func_name,"---Top---");
+ Static_mem_head->mem_usage = 0;
+ Static_mem_head->mem_usage_acc = 0;
+ Static_mem_head->parent = NULL;
+ Static_mem_head->next = NULL;
+ Static_mem_curr = Static_mem_head;
+}
+
+void P_Sta_Mem_Add(const char *func_name,
+ long mem_usage)
+{
+ /* Enter a new function, push on the stack */
+ Static_mem_curr->next = (C_Path*) malloc (sizeof(C_Path));
+ Static_mem_curr->next->parent = Static_mem_curr;
+ Static_mem_curr = Static_mem_curr->next;
+ Static_mem_curr->next = NULL;
+ /* save function name */
+ strcpy(Static_mem_curr->func_name,func_name);
+ /* save memory usage */
+ Static_mem_curr->mem_usage = mem_usage;
+ /* update memory usage accumulator */
+ Static_mem_curr->mem_usage_acc = Static_mem_curr->parent->mem_usage_acc + mem_usage;
+}
+
+void P_Sta_Mem_Exit(void)
+{
+ C_Path *node;
+ /* fprintf(stderr,"\n Static memory usage = %ld kWords (%ld bytes)\n Detailed Memory Usage", Static_mem_curr->mem_usage_acc/(1000*2),Static_mem_curr->mem_usage_acc); */
+ fprintf(stderr,"\n Static memory usage = %.2f kWords (%ld bytes)\n Detailed Memory Usage", (ceil((float)Static_mem_curr->mem_usage_acc/20.f)/100.f),Static_mem_curr->mem_usage_acc);
+
+ node = Static_mem_head->next;
+ while (node != NULL) {
+ fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage);
+ node=node->next;
+ }
+
+ fprintf(stderr,"\n");
+
+#ifdef CTEST_MEASUREMENTS
+ printf("%.3f\n", "statMem [kWords]", "numeric/float", Static_mem_curr->mem_usage_acc/(1000.0*2));
+#endif
+
+ path_free(Static_mem_head);
+}
+
+void P_Sta_Mem_Exit_noprint(void)
+{
+ path_free(Static_mem_head);
+}
diff --git a/lib_lc3plus/dynmem.h b/lib_lc3plus/dynmem.h
new file mode 100644
index 0000000000000000000000000000000000000000..e81169a3379a3ab3e601f397bccbd00330e00c56
--- /dev/null
+++ b/lib_lc3plus/dynmem.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+
+#ifndef DYNMEM_H
+#define DYNMEM_H
+
+#ifdef _MSC_VER
+/* This disables warnings about anonymous temporary struct declarations */
+#pragma warning(disable:4115)
+#pragma warning(disable:4116)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void P_Dyn_Mem_Init(void);
+void P_Dyn_Mem_In(const char *func_name,
+ long mem_usage);
+void P_Dyn_Mem_Add(long mem_usage);
+void P_Dyn_Mem_Out(void);
+void P_Dyn_Mem_Exit(void);
+void P_Dyn_Mem_Exit_noprint(void);
+
+void P_Sta_Mem_Init(void);
+void P_Sta_Mem_Add(const char *func_name,
+ long mem_usage);
+void P_Sta_Mem_Exit(void);
+void P_Sta_Mem_Exit_noprint(void);
+
+#ifdef DONT_COUNT_MEM
+
+#define Dyn_Mem_Init()
+#define Dyn_Mem_Exit()
+#define Dyn_Mem_Exit_noprint()
+#define Dyn_Mem_In(a,b)
+#define Dyn_Mem_Add(b)
+#define Dyn_Mem_Out()
+
+#define DYN_MEM_IN Dyn_Mem_In
+#define DYN_MEM_ADD Dyn_Mem_Add
+#define DYN_MEM_OUT Dyn_Mem_Out
+
+#define Sta_Mem_Init()
+#define Sta_Mem_Exit()
+#define Sta_Mem_Exit_noprint()
+#define Sta_Mem_Add(a,b)
+
+#else /* DONT_COUNT_MEM */
+
+#define Dyn_Mem_Init P_Dyn_Mem_Init
+#define Dyn_Mem_Exit P_Dyn_Mem_Exit
+#define Dyn_Mem_Exit_noprint P_Dyn_Mem_Exit_noprint
+#define Dyn_Mem_In P_Dyn_Mem_In
+#define Dyn_Mem_Add P_Dyn_Mem_Add
+#define Dyn_Mem_Out P_Dyn_Mem_Out
+
+#define DYN_MEM_IN P_Dyn_Mem_In
+#define DYN_MEM_ADD P_Dyn_Mem_Add
+#define DYN_MEM_OUT P_Dyn_Mem_Out
+
+#define Sta_Mem_Init P_Sta_Mem_Init
+#define Sta_Mem_Exit P_Sta_Mem_Exit
+#define Sta_Mem_Exit_noprint P_Sta_Mem_Exit_noprint
+#define Sta_Mem_Add P_Sta_Mem_Add
+
+#endif /* DONT_COUNT_MEM */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c
new file mode 100644
index 0000000000000000000000000000000000000000..35dd8d95064901dd5061436dfbb808011ac35b6d
--- /dev/null
+++ b/lib_lc3plus/enc_entropy.c
@@ -0,0 +1,173 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static Word32 ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */
+ const Word32 L_szA, /* i: max 22 bits */
+ const Word32 L_szB, /* i: max 4 bits */
+ const Word32 L_cwA, const Word32 L_cwB);
+
+void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes,
+ Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters,
+ Word16 lsbMode, Word16 lastnz, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx,
+ Word16 BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx)
+{
+ Word16 tmp;
+ Word32 L_tmp;
+ Word16 submode_LSB, submode_MSB, gain_MSBs;
+ Word32 L_gain_LSB;
+ Counter n;
+ UWord8 *ptr;
+
+ Word16 lastnzTrigger[5] = {63, 127, 127, 255, 255};
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Word16 tmp;
+ Word32 L_tmp;
+ Word16 submode_LSB, submode_MSB, gain_MSBs;
+ Word32 L_gain_LSB;
+ Counter n;
+ UWord8 *ptr;
+ Word16 lastnzTrigger[5];
+ };
+ Dyn_Mem_In("processEncoderEntropy", sizeof(struct _dynmem));
+#endif
+
+ /* Init */
+ *bp_side = shr_pos(sub(nbbits, 1), 3);
+ *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3))));
+ ptr = bytes;
+
+ basop_memset(bytes, 0, targetBytes * sizeof(*bytes));
+
+ /* Cutoff-detection */
+ IF (BW_cutoff_bits > 0)
+ {
+ write_indice_backward(ptr, bp_side, mask_side, BW_cutoff_idx, BW_cutoff_bits);
+ }
+
+ /* Encode last non-zero tuple */
+ tmp = sub(14, norm_s(negate(L_spec)));
+
+ IF (sub(bfi_ext, 1) == 0)
+ {
+ write_indice_backward(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], tmp);
+ }
+ ELSE
+ {
+ write_indice_backward(ptr, bp_side, mask_side, sub(shr_pos(lastnz, 1), 1), tmp);
+ }
+
+ /* Mode bit */
+ write_bit_backward(ptr, bp_side, mask_side, lsbMode);
+
+ /* Encode global-gain */
+ write_indice_backward(ptr, bp_side, mask_side, gg_idx, 8);
+
+ /* TNS on/off flag */
+ FOR (n = 0; n < tns_numfilters; n++)
+ {
+ write_bit_backward(ptr, bp_side, mask_side, s_min(tns_order[n], 1));
+ }
+
+ /* LTPF on/off*/
+ write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[0], 1);
+
+ /* Encode SCF VQ parameters - 1st stage (10 bits) */
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[0]), 5); /* stage1 LF 5 bits */
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[1]), 5); /* stage1 HF 5 bits */
+
+ /* Encode SCF VQ parameters - 2nd stage side-info (3-4 bits) */
+ submode_MSB = shr_pos(extract_l(L_scf_idx[2]), 1); /* explicit tx */
+ write_bit_backward(ptr, bp_side, mask_side, submode_MSB); /* submode MSB 1 explicit bit */
+ submode_LSB = s_and(extract_l(L_scf_idx[2]), 0x1); /* for joint coding with shapeCw */
+ gain_MSBs = extract_l(L_scf_idx[3]); /* all gain bits */
+ L_gain_LSB = L_and(L_scf_idx[3], 0x1L);
+ gain_MSBs = shr(gain_MSBs, sns_gainLSBbits[L_scf_idx[2]]);
+
+ ASSERT(gain_MSBs >= 0 && gain_MSBs < (1 << sns_gainMSBbits[L_scf_idx[2]])); /* ASSERT max 2 MSB(s) in gain bits */
+
+ write_indice_backward(ptr, bp_side, mask_side, gain_MSBs,
+ sns_gainMSBbits[L_scf_idx[2]]); /* adjgain or MSBs of adjGains 1-2 bits */
+ write_bit_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[4])); /* shape LS 1 bit */
+
+ /* Encode SCF VQ parameters - 2nd stage data (24-25 bits) */
+ IF (submode_MSB == 0)
+ { /* regular,regular_lf*/
+ ASSERT(submode_MSB == 0);
+
+ L_tmp = L_add(L_gain_LSB, 0); /* gain-LSB 0,1 for regular_lf, offset is 0 */
+ if (submode_LSB == 0)
+ {
+ L_tmp = L_add(L_scf_idx[6],
+ sns_MPVQ_Sz[1][1]); /* shape B pos offset is 2 , upshifted two positions , 0..11 -> 2..13 */
+ }
+ /* regular mode A,B indexes multiplexed, total 24.x bits MPVQ codeword section A + codeword for section B */
+ L_tmp = ac_enc_mux_st2VQ_cws(sns_MPVQ_Sz[0][0], /* max 21.3 bits*/
+ UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* max log2(14) bits */
+ L_scf_idx[5] /* shapeA */, L_tmp /* shapeB joint with adjGainLSB */);
+ /* regular mode mode shape index total 1+23.9999 bits MPVQ codeword */
+ ASSERT(L_tmp < (1L << 25));
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 13); /* multiplex 13 bits */
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr_pos(L_tmp, 13)), 12); /* multiplex 12 bits */
+ }
+ ELSE
+ { /* outlier near, outlier far */
+ ASSERT(submode_MSB == 1);
+ L_tmp = L_scf_idx[5]; move32(); /* outlier near section assumed */
+ if (submode_LSB != 0)
+ { /* outl_far */
+ L_tmp = L_add(L_shl_pos(L_tmp, 1), L_gain_LSB); /* add lsb bit of Gain */
+ L_tmp = L_add(L_tmp, sns_MPVQ_Sz[2][0]); /* outlier far section offset added */
+ }
+
+ ASSERT(L_tmp < (1L << 24));
+ /* outlier mode shape index total 23.8536 ( + ~.14 ) bits as MPVQ codeword */
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 12); /* multiplex 12 bits LSB*/
+ write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr(L_tmp, 12)), 12); /* multiplex 12 bits MSBs */
+ }
+
+ /* LTPF data */
+ IF (ltpf_idx[0] != 0)
+ {
+ write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[1], 1);
+ write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[2], 9);
+ }
+
+ /* Encoder noise-fac */
+ write_indice_backward(ptr, bp_side, mask_side, fac_ns_idx, 3);
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static __forceinline Word32
+ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */
+ const Word32 L_szA, /* i: max 22 bits */
+ const Word32 L_szB, /* i: max 4 bits 0..13 */
+ const Word32 L_cwA,
+ const Word32 L_cwB) /* [0..13} corresponding to gains{0,1}, shapeB{0..11} or */
+{
+
+ Word32 L_cwTx;
+ /* L_cw_tx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */
+ L_cwTx = (Word32)UL_Mpy_32_32(
+ (UWord32)L_cwB, (UWord32)L_szA); /* non-fractional 16x32 -> 32 may possibly also be used if available */
+ L_cwTx = L_add(L_cwTx, L_cwA);
+
+ ASSERT((L_szA * L_szB) <= 1 << 25); /* multiplexing only allowed up to 25 bits (+ leading sign) */
+ ASSERT(L_cwTx >= 0 && L_cwTx <= 0x01ffFFff); /* max 25 bits allowed */
+ UNUSED(L_szB);
+
+ return L_cwTx;
+}
diff --git a/lib_lc3plus/enc_lc3.c b/lib_lc3plus/enc_lc3.c
new file mode 100644
index 0000000000000000000000000000000000000000..30ff9971b4599b64533ecf78d8ded9cc4b18a222
--- /dev/null
+++ b/lib_lc3plus/enc_lc3.c
@@ -0,0 +1,680 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include // ToDo: probably to be removed
+
+static void Enc_LC3PLUS_Channel(LC3PLUS_Enc *encoder, int channel, int bits_per_sample, Word32 *s_in, UWord8 *bytes,
+ Word8 *scratchBuffer, int bfi_ext)
+{
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(Word16 d_fx_exp;
+ Word16 gain_e, gain, quantizedGain, quantizedGainMin;
+ Word16 ener_fx_exp;
+ Word16 pitch, normcorr;
+ Word16 ltpf_bits;
+ Word16 tns_numfilters;
+ Word16 lsbMode, lastnz, BW_cutoff_idx;
+ Word16 gainChange, fac_ns_idx;
+ Word16 nBits, numResBits;
+ Word16 bp_side, mask_side;
+ Word16 s_12k8_len;
+ Word16 b_left;
+ Word32 * L_scf_idx;
+ Word32 * d_fx, *ener_fx;
+ Word16 * s_12k8, *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX], *indexes;
+ Word32 * q_d_fx24;
+ Word16 * scf;
+ Word16 * codingdata;
+ Word32 * scf_q, *int_scf_fx;
+ Word32 * s_in_scaled;
+ Word16 * s_in_scaled_lp;
+ UWord8 * resBits;
+ Word16 ltpf_idx[3];
+ EncSetup * h_EncSetup;
+ Word8 * currentScratch;
+ Word16 hrmode;
+ );
+#else
+ Dyn_Mem_Deluxe_In(Word16 d_fx_exp; Word16 gain_e, gain, quantizedGain, quantizedGainMin; Word16 ener_fx_exp;
+ Word16 pitch, normcorr; Word16 ltpf_bits; Word16 tns_numfilters;
+ Word16 lsbMode, lastnz, BW_cutoff_idx; Word16 gainChange, fac_ns_idx; Word16 nBits, numResBits;
+ Word16 bp_side, mask_side; Word16 s_12k8_len; Word16 b_left;
+
+ Word32 * L_scf_idx; Word32 * d_fx, *ener_fx;
+ Word16 * s_12k8, *int_scf_fx_exp, *q_d_fx16, *int_scf_fx, tns_order[TNS_NUMFILTERS_MAX], *indexes;
+ Word16 * scf, *scf_q; Word16 * codingdata; Word16 * s_in_scaled; UWord8 * resBits;
+ Word8 * currentScratch; Word16 ltpf_idx[3]; EncSetup * h_EncSetup;);
+#endif /* ENABLE_HR_MODE */
+
+ h_EncSetup = encoder->channel_setup[channel];
+
+#ifdef ENABLE_HR_MODE
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ hrmode = encoder->hrmode;
+# endif
+#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+#ifdef WMOPS
+ BASOP_sub_start("Encoder");
+#endif
+
+ /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole encoding process */
+ d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */
+ L_scf_idx = scratchAlign(
+ d_fx, sizeof(*d_fx) * s_max(80, encoder->frame_length)); /* Size = 4 * SCF_MAX_PARAM -> aligned to 32 bytes */
+ indexes = scratchAlign(L_scf_idx,
+ sizeof(*L_scf_idx) * SCF_MAX_PARAM); /* Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */
+
+#ifdef ENABLE_HR_MODE
+ q_d_fx24 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG));
+#else
+ q_d_fx16 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG)); /* Size = 2 * MAX_LEN bytes */
+#endif /* ENABLE_HR_MODE */
+
+#ifdef ENABLE_HR_MODE
+ codingdata =
+ scratchAlign(q_d_fx24, sizeof(*q_d_fx24) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */
+#else
+ codingdata =
+ scratchAlign(q_d_fx16, sizeof(*q_d_fx16) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */
+#endif
+
+#ifdef ENABLE_HR_MODE
+ ener_fx = scratchAlign(q_d_fx24, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */
+ s_in_scaled = scratchAlign(q_d_fx24, 0); /* Size = 2 * MAX_LEN bytes */
+#else
+ ener_fx = scratchAlign(q_d_fx16, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */
+ s_in_scaled = scratchAlign(q_d_fx16, 0); /* Size = 2 * MAX_LEN bytes */
+#endif
+
+#ifdef ENABLE_HR_MODE
+ s_in_scaled_lp = (Word16 *)s_in_scaled;
+#endif
+
+#ifdef ENABLE_HR_MODE
+ /* allocate memory for residual bits */
+ if (encoder->hrmode)
+ {
+ resBits = scratchAlign(codingdata, sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2));
+ }
+ else
+#endif /* #ifdef ENABLE_HR_MODE */
+ {
+ resBits = scratchAlign(codingdata,
+ sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2)); /* Size = MAX_LEN bytes */
+ }
+
+ {
+#ifdef ENABLE_HR_MODE
+ currentScratch =
+ scratchAlign(resBits, sizeof(*resBits) * MAX_RESBITS_LEN); /* Size = 4 * MAX_LEN */
+#else
+ currentScratch =
+ scratchAlign(resBits, sizeof(*resBits) * s_max(80, encoder->frame_length)); /* Size = 4 * MAX_LEN */
+#endif /* #ifdef ENABLE_HR_MODE */
+ }
+
+ s_12k8 = scratchAlign(
+ s_in_scaled,
+ sizeof(*s_in_scaled) *
+ s_max(80, encoder->frame_length)); /* Size = 2 * (LEN_12K8 + 1) = 258 bytes -> aligned to 288 bytes */
+ scf_q = scratchAlign(ener_fx, sizeof(*ener_fx) * MAX_BANDS_NUMBER); /* Size = 2 * M */
+ scf = scratchAlign(scf_q, sizeof(*scf_q) * M); /* Size = 2 * M */
+ int_scf_fx = scratchAlign(scf, sizeof(*scf) * M); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+ int_scf_fx_exp =
+ scratchAlign(int_scf_fx, sizeof(*int_scf_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+
+ /* Scale 24-bit input data */
+ IF (sub(bits_per_sample, 24) == 0)
+ {
+#ifdef WMOPS
+ BASOP_sub_start("Scale_signal24");
+#endif
+ scale_signal24_fx(s_in, s_in_scaled, &h_EncSetup->x_exp, h_EncSetup->stEnc_mdct_mem,
+ encoder->stEnc_mdct_mem_len, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len,
+ h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len,
+ h_EncSetup->mdct_mem32, encoder->frame_length, h_EncSetup->resamp_mem32,
+ h_EncSetup->olpa_mem_s12k8, &h_EncSetup->resamp_exp);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+ }
+ ELSE
+ {
+#ifdef ENABLE_HR_MODE
+ Word16 *ip_buf = (Word16*)s_in;
+ Word32 i;
+ FOR(i = 0; i < encoder->frame_length; i++)
+ {
+ s_in_scaled[i] = L_deposit_h(ip_buf[i]);
+ }
+ h_EncSetup->x_exp = 15; move16();
+#else
+ memcpy(s_in_scaled, s_in, encoder->frame_length * sizeof(*s_in_scaled));
+#endif
+ }
+
+#ifdef WMOPS
+ BASOP_sub_start("Mdct");
+#endif
+
+ /* currentScratch Size = 4 * MAX_LEN */
+ processMdct_fx(s_in_scaled, h_EncSetup->x_exp, encoder->frame_length,
+#ifdef ENABLE_HR_MODE
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ hrmode,
+# endif
+#endif
+ encoder->W_fx, encoder->W_size,
+ h_EncSetup->stEnc_mdct_mem, encoder->stEnc_mdct_mem_len, d_fx, &d_fx_exp, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ /* begin s_12k8 */
+#ifdef WMOPS
+ BASOP_sub_start("Resamp12k8");
+#endif
+ /* currentScratch Size = 2.25 * MAX_LEN bytes */
+#ifdef ENABLE_HR_MODE
+ downshift_w32_arr(s_in_scaled, s_in_scaled_lp, 16, encoder->frame_length); /* s_in_scaled is no longer required */
+
+ process_resamp12k8_fx(s_in_scaled_lp, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len,
+ h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8,
+ &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch
+ , bits_per_sample
+ );
+#else
+ process_resamp12k8_fx(s_in_scaled, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len,
+ h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8,
+ &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch
+ , bits_per_sample
+ );
+#endif /* ENABLE_HR_MODE */
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Olpa");
+#endif
+ /* currentScratch Size = 392 bytes */
+ process_olpa_fx(&h_EncSetup->olpa_mem_s6k4_exp, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, &pitch,
+ s_12k8, s_12k8_len, &normcorr, &h_EncSetup->olpa_mem_pitch,
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ &h_EncSetup->pitch_flag,
+#endif
+ h_EncSetup->resamp_exp, encoder->frame_dms, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("LtpfEnc");
+#endif
+ /* currentScratch Size = 512 bytes */
+ process_ltpf_coder_fx(<pf_bits, pitch, h_EncSetup->ltpf_enable, &h_EncSetup->ltpf_mem_in_exp,
+ h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, ltpf_idx, s_12k8, s_12k8_len,
+ &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_mem_normcorr, normcorr,
+ &h_EncSetup->ltpf_mem_ltpf_on, &h_EncSetup->ltpf_mem_pitch, h_EncSetup->resamp_exp,
+ encoder->frame_dms, currentScratch
+#ifdef CR9_K_REDUCE_NORM_CORR_TH
+ ,encoder->hrmode
+#endif
+);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ /* end s_12k8 */
+#ifdef WMOPS
+ BASOP_sub_start("AttackDetector");
+#endif
+ /* currentScratch Size = ??? bytes */
+#ifdef ENABLE_HR_MODE
+ attack_detector_fx(encoder, h_EncSetup, s_in_scaled_lp, sub(h_EncSetup->x_exp, 15), currentScratch);
+#else
+ attack_detector_fx(encoder, h_EncSetup, s_in_scaled, sub(h_EncSetup->x_exp, 15), currentScratch);
+#endif
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ /* begin ener_fx */
+#ifdef WMOPS
+ BASOP_sub_start("PerBandEnergy");
+#endif
+ /* currentScratch Size = 160 bytes */
+ processPerBandEnergy_fx(ener_fx, &ener_fx_exp, d_fx, d_fx_exp, encoder->bands_offset, encoder->fs_idx,
+ encoder->bands_number, 0, encoder->frame_dms, currentScratch
+#ifdef ENABLE_HR_MODE
+ , encoder->hrmode
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Near Nyquist Detector");
+#endif
+ /* Near Nyquist Detector */
+ processNearNyquistdetector_fx(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index,
+ encoder->bands_number, ener_fx, ener_fx_exp
+#ifdef CR8_E_TONE_DETECTOR
+#ifdef ENABLE_HR_MODE
+ , encoder->frame_dms, encoder->hrmode );
+#else
+ );
+#endif
+#else
+ );
+#endif
+ /* Disable LTPF if nyquist detector triggers */
+ IF (encoder->near_nyquist_flag != 0 || sub(h_EncSetup->lfe, 1) == 0)
+ {
+ h_EncSetup->ltpf_mem_ltpf_on = 0; move16();
+ ltpf_idx[1] = 0; move16();
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+#ifdef WMOPS
+ BASOP_sub_start("BW Cutoff-Detection");
+#endif
+ IF (h_EncSetup->lfe == 0)
+ {
+#ifdef ENABLE_HR_MODE
+ /* No BW Cutoff for 8 kHz and 96 kHz */
+ IF (encoder->fs_idx > 0 && encoder->hrmode == 0 && encoder->bw_ctrl_active == 0)
+ {
+#else /* ENABLE_HR_MODE */
+ IF (encoder->fs_idx > 0 && encoder->bw_ctrl_active == 0)
+ {
+#endif /* ENABLE_HR_MODE */
+ processDetectCutoffWarped_fx(&BW_cutoff_idx, ener_fx, ener_fx_exp, encoder->fs_idx, encoder->frame_dms);
+ }
+ ELSE
+ {
+ BW_cutoff_idx = encoder->fs_idx;
+ move16();
+ }
+ }
+ ELSE
+ {
+ BW_cutoff_idx = 0;
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("SnsCompScf");
+#endif
+
+
+ /* currentScratch Size = 512 bytes */
+ processSnsComputeScf_fx(ener_fx, ener_fx_exp, encoder->fs_idx, encoder->bands_number, scf,
+ h_EncSetup->attdec_detected, encoder->attdec_damping, currentScratch, encoder->sns_damping
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("SnsQuantScfEnc");
+#endif
+ /* currentScratch Size = 500 bytes */
+
+ processSnsQuantizeScfEncoder_fx(scf, L_scf_idx, scf_q, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("SnsInterpScfEnc");
+#endif
+ /* currentScratch Size = 128 bytes */
+ processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 1, encoder->bands_number, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Mdct shaping_enc");
+#endif
+ processMdctShaping_fx(d_fx, int_scf_fx, int_scf_fx_exp, encoder->bands_offset, encoder->bands_number);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+ /* end int_scf_fx_exp */
+#ifdef WMOPS
+ BASOP_sub_start("BandwidthControl_enc");
+#endif
+ if (encoder->bandwidth < L_shr_pos(encoder->fs, 1))
+ {
+ process_cutoff_bandwidth(d_fx, encoder->yLen, encoder->bw_ctrl_cutoff_bin);
+ BW_cutoff_idx = s_min(BW_cutoff_idx, encoder->bw_index);
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+#ifdef WMOPS
+ BASOP_sub_start("Tns_enc");
+#endif
+ /* currentScratch Size = 2 * MAX_LEN + 220 */
+
+ IF (h_EncSetup->lfe == 0)
+ {
+ processTnsCoder_fx(&(h_EncSetup->tns_bits), indexes, d_fx, BW_cutoff_idx, tns_order, &tns_numfilters,
+ h_EncSetup->enable_lpc_weighting, encoder->nSubdivisions, encoder->frame_dms,
+ encoder->frame_length, currentScratch
+#ifdef ENABLE_HR_MODE
+ , encoder->hrmode
+#endif
+ , encoder->near_nyquist_flag
+ );
+ }
+ ELSE
+ {
+ tns_numfilters = 1;
+ move16();
+ tns_order[0] = 0;
+ move16();
+ h_EncSetup->tns_bits = tns_numfilters;
+ move16();
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Est. Global Gain");
+#endif
+ /* currentScratch Size = 4 * MAX_LEN bytes */
+ h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits));
+
+ test();
+ IF (h_EncSetup->targetBitsQuant < 0 && sub(ltpf_bits, 1) > 0)
+ {
+ /* Disable LTPF */
+ h_EncSetup->ltpf_mem_ltpf_on = 0; move16();
+ ltpf_idx[1] = 0; move16();
+ ltpf_bits = 1; move16();
+ h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits));
+ }
+
+#ifdef ENABLE_HR_MODE
+ Word32 gain32;
+#endif
+
+ processEstimateGlobalGain_fx(d_fx, d_fx_exp, encoder->yLen, h_EncSetup->targetBitsQuant,
+#ifdef ENABLE_HR_MODE
+ &gain32,
+#else
+ &gain,
+#endif
+ &gain_e,
+ &quantizedGain, &quantizedGainMin, h_EncSetup->quantizedGainOff,
+ &h_EncSetup->targetBitsOff, &h_EncSetup->mem_targetBits, h_EncSetup->mem_specBits,
+ currentScratch
+#ifdef ENABLE_HR_MODE
+ , encoder->hrmode, h_EncSetup->regBits, encoder->frame_dms
+#endif
+ );
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+ /* begin q_d_fx16 */
+
+#ifdef WMOPS
+ BASOP_sub_start("Quant. 1");
+#endif
+#ifdef ENABLE_HR_MODE
+ processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant,
+ h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz,
+ codingdata, &lsbMode, -1, encoder->hrmode);
+
+#else
+ processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant,
+ h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz,
+ codingdata, &lsbMode, -1);
+#endif /* ENABLE_HR_MODE */
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Adj. Global Gain");
+#endif
+#ifdef ENABLE_HR_MODE
+ //gain32 = L_shl_pos((Word32)gain, 16);
+ processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain32, &gain_e,
+ h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx
+ , encoder->hrmode, encoder->frame_dms
+ );
+ gain = round_fx(gain32);
+#else
+ processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain, &gain_e,
+ h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx);
+#endif /* ENABLE_HR_MODE */
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Quant. 2");
+#endif
+ IF (sub(gainChange, 1) == 0)
+ {
+#ifdef ENABLE_HR_MODE
+ processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant,
+ h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode,
+ 0, encoder->hrmode);
+#else
+ processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant,
+ h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode,
+ 0);
+#endif /* ENABLE_HR_MODE */
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Res. Cod.");
+#endif
+ IF (lsbMode == 0)
+ {
+ processResidualCoding_fx(d_fx_exp, d_fx,
+#ifdef ENABLE_HR_MODE
+ q_d_fx24,
+#else
+ q_d_fx16,
+#endif
+#ifdef ENABLE_HR_MODE
+ gain32,
+#else
+ gain,
+#endif
+ gain_e, encoder->yLen, h_EncSetup->targetBitsQuant, nBits, resBits, &numResBits
+#ifdef ENABLE_HR_MODE
+ , encoder->hrmode
+#endif
+ );
+ }
+ ELSE
+ {
+ numResBits = 0;
+ move16();
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Noise fac");
+#endif
+ /* currentScratch Size = 2 * MAX_LEN bytes */
+ IF (h_EncSetup->lfe == 0)
+ {
+ processNoiseFactor_fx(&fac_ns_idx, d_fx_exp, d_fx,
+#ifdef ENABLE_HR_MODE
+ q_d_fx24,
+#else
+ q_d_fx16,
+#endif
+ gain, gain_e, BW_cutoff_idx, encoder->frame_dms, h_EncSetup->targetBytes, currentScratch
+#ifdef ENABLE_HR_MODE
+ , encoder->hrmode
+#endif
+ );
+ }
+ ELSE
+ {
+ fac_ns_idx = 7;
+ move16();
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Entropy cod");
+#endif
+ processEncoderEntropy(bytes, &bp_side, &mask_side, h_EncSetup->targetBitsAri, h_EncSetup->targetBytes,
+ encoder->yLen, encoder->BW_cutoff_bits, tns_numfilters, lsbMode, lastnz, tns_order,
+ fac_ns_idx, quantizedGain, BW_cutoff_idx, ltpf_idx, L_scf_idx, bfi_ext, encoder->fs_idx);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Ari cod");
+#endif
+ processAriEncoder_fx(bytes, bp_side, mask_side, h_EncSetup->targetBitsAri,
+#ifdef ENABLE_HR_MODE
+ q_d_fx24,
+#else
+ q_d_fx16,
+#endif
+ tns_order, tns_numfilters, indexes, lastnz, codingdata, resBits, numResBits, lsbMode,
+ h_EncSetup->enable_lpc_weighting, currentScratch);
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_start("Reorder Bitstream Enc");
+#endif
+ test();
+ IF (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0)
+ {
+#ifdef WMOPS
+ BASOP_sub_start("Reorder Ari dec");
+#endif
+
+#ifdef ENABLE_HR_MODE
+ Word32 *xbuf = (Word32 *) scratchAlign(scratchBuffer, 0);
+
+ processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx,
+ h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order,
+ fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0,
+ shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain,
+ xbuf,
+ &gain, resBits, indexes, &gain,
+ currentScratch
+ , encoder->hrmode
+ );
+#else
+
+ processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx,
+ h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order,
+ fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0,
+ shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain,
+ codingdata,
+ &gain, resBits, indexes, &gain,
+ currentScratch
+ );
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_end(); /* Ari dec */
+#endif
+ processReorderBitstream_fx(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, currentScratch);
+ }
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ /* end q_d_fx16 */
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext)
+{
+ int ch = 0, output_size = 0;
+ int input_size = 0;
+ int totalBytes = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in);
+ int output_size2;
+
+ UWord8 *lc3buf = output;
+
+ for (ch = 0; ch < encoder->channels; ch++)
+ {
+ Enc_LC3PLUS_Channel(encoder, ch, bits_per_sample, input[ch], lc3buf, scratch, bfi_ext);
+ if (encoder->epmode && encoder->combined_channel_coding == 0)
+ {
+ output_size2 = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels));
+#ifdef WMOPS
+ BASOP_sub_start("fec_enc");
+#endif
+
+ fec_encoder(encoder->epmode, encoder->epmr, lc3buf, encoder->channel_setup[ch]->targetBytes, output_size2,
+ encoder->channel_setup[ch]->n_pccw, scratch);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+
+ lc3buf += output_size2;
+ output_size += output_size2;
+ }
+ else
+ {
+ lc3buf += encoder->channel_setup[ch]->targetBytes;
+ output_size += encoder->channel_setup[ch]->targetBytes;
+ }
+ }
+
+ if (encoder->epmode > 0 && encoder->combined_channel_coding)
+ {
+ input_size = output_size;
+ output_size = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in);
+#ifdef WMOPS
+ BASOP_sub_start("fec_enc");
+#endif
+
+ fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw,
+ scratch);
+
+#ifdef WMOPS
+ BASOP_sub_end();
+#endif
+ }
+
+ return output_size;
+}
+
diff --git a/lib_lc3plus/estimate_global_gain_fx.c b/lib_lc3plus/estimate_global_gain_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6d1766b43d2fdac7e8500cddde1215766bb671c
--- /dev/null
+++ b/lib_lc3plus/estimate_global_gain_fx.c
@@ -0,0 +1,506 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 nbitsSQ,
+#ifdef ENABLE_HR_MODE
+ Word32 *gain,
+#else
+ Word16 *gain,
+#endif
+ Word16 *gain_e,
+ Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff,
+ Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode, Word16 regBits, Word16 frame_dms
+#endif
+)
+{
+
+ Word16 lg_4, tmp16, iszero, s;
+ Word32 ener, tmp32, x_max;
+ Word32 target, fac, offset;
+ Word32 *en;
+ Counter iter, i;
+ Word32 diff, diff2;
+#ifdef ENABLE_HR_MODE
+ Word16 *en_exp = NULL;
+ Word32 M0, M1;
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processEstimateGlobalGain_fx", sizeof(struct {
+ Word16 lg_4, s, tmp16, iszero;
+ Word32 ener, tmp32, x_max;
+ Word32 target, fac, offset;
+ Word32 *en;
+ Counter i, iter;
+ Word32 diff, diff2;
+ }));
+#endif
+
+ en = (Word32 *)scratchAlign(scratchBuffer,
+ 0); /* Size = MAX_LEN bytes */
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ M0 = 1;
+ M1 = 1; /* Regularization factor; needs´to be 1e-5, but 1e-5 is 0 in Q15 */
+ en_exp = (Word16 *) scratchAlign(en, sizeof(*en) * MAX_LEN);
+ }
+#endif
+ IF (*old_targetBits < 0)
+ {
+ *targetBitsOff = 0;
+ move16();
+ }
+ ELSE
+ {
+ tmp32 = L_add(*targetBitsOff, L_deposit_h(sub(*old_targetBits, old_specBits)));
+ tmp32 = L_min((40 << 16), L_max(-(40 << 16), tmp32));
+ *targetBitsOff = L_add(Mpy_32_16_lc3plus(*targetBitsOff, 26214), Mpy_32_16_lc3plus(tmp32, 6554));
+ move16();
+ }
+
+ *old_targetBits = nbitsSQ;
+ move16();
+ nbitsSQ = add(nbitsSQ, round_fx(*targetBitsOff));
+
+ lg_4 = shr_pos(lg, 2);
+ x_max = 0;
+ move32();
+
+/* energy of quadruples with 9dB offset */
+#ifdef ENABLE_HR_MODE
+ IF (hrmode)
+ {
+ FOR (i = 0; i < lg_4; i++)
+ {
+ Word32 absval;
+ Word16 idx;
+ /* normalization */
+ s = 31;
+ move16();
+
+ /* M1 requires a 32x16 mult with Q0 i, resulting in Q15. Keeping both M0 and M1 in same Q */
+ /* Use Q15 for M0 and M1 calculation */
+ idx = shl(i, 2);
+
+ tmp32 = L_abs(x[0]);
+ absval = L_shr(tmp32, 16);
+ M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/
+ M1 = L_add(M1, L_mult(absval, idx)); /* M1 += i*fabs(x[idx])*/
+ idx = add(idx, 1);
+
+ absval = L_abs(x[1]);
+ tmp32 = L_max(tmp32, absval);
+ absval = L_shr(tmp32, 16);
+ M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/
+ M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/
+ idx = add(idx, 1);
+
+ absval = L_abs(x[2]);
+ tmp32 = L_max(tmp32, absval);
+ absval = L_shr(tmp32, 16);
+ M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/
+ M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/
+ idx = add(idx, 1);
+
+ absval = L_abs(x[3]);
+ tmp32 = L_max(tmp32, absval);
+ absval = L_shr(tmp32, 16);
+ M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/
+ M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/
+
+ x_max = L_max(x_max, tmp32);
+
+ if (tmp32 != 0)
+ s = norm_l(tmp32);
+
+ s = sub(s, 2); /* 2 bits headroom */
+
+ /* calc quadruple energy */
+ ener = L_deposit_l(1);
+
+ tmp16 = round_fx(L_shl(x[0], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[1], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[2], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[3], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ s = shl_pos(sub(x_e, s), 1);
+ if (ener == 1 && s < 0)
+ s = 0;
+ IF (regBits > 0)
+ {
+ en[i] = ener;
+ en_exp[i] = s;
+ move32();
+ }
+ ELSE
+ {
+ /* log */
+ tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */
+ tmp32 = L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 7),
+ 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 16Q15 */
+ en[i] = tmp32;
+ move32();
+ }
+
+ x += 4;
+ }
+ }
+ ELSE
+#endif
+ {
+ FOR (i = 0; i < lg_4; i++)
+ {
+ /* normalization */
+ s = 31;
+ move16();
+
+ tmp32 = L_abs(x[0]);
+ tmp32 = L_max(tmp32, L_abs(x[1]));
+ tmp32 = L_max(tmp32, L_abs(x[2]));
+ tmp32 = L_max(tmp32, L_abs(x[3]));
+ x_max = L_max(x_max, tmp32);
+
+ if (tmp32 != 0)
+ s = norm_l(tmp32);
+
+ s = sub(s, 2); /* 2 bits headroom */
+
+ /* calc quadruple energy */
+ ener = L_deposit_l(1);
+
+ tmp16 = round_fx(L_shl(x[0], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[1], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[2], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ tmp16 = round_fx(L_shl(x[3], s));
+ ener = L_mac(ener, tmp16, tmp16);
+
+ s = shl_pos(sub(x_e, s), 1);
+ if (ener == 1 && s < 0)
+ s = 0;
+
+ /* log */
+ tmp32 = L_add_sat(BASOP_Util_Log2_lc3plus(ener), L_shl_sat(L_deposit_l(s), 25)); /* log2, 6Q25 */
+ tmp32 =
+ L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 6), 0x9CCCD); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */
+ en[i] = tmp32;
+ move32();
+ x += 4;
+ }
+ }
+
+ IF (x_max == 0)
+ {
+ *quantizedGainMin = quantizedGainOff;
+ move16();
+ *quantizedGain = 0;
+ move16();
+ *old_targetBits = -1;
+ move16();
+ }
+ ELSE
+ {
+ Word32 sub_val = 0xFCDD38F;
+ /*28 * log10(32767 - 0.375) * (1 - 1e-7) in Q21 */
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ /*
+ Original float code :
+ rB_offset = 8 * (1 - MIN(M1/M0, 2*frame_ms)/(2*frame_ms)
+ */
+ Word16 ratio;
+ Word16 ratio_exp = 0;
+ Word32 regterm = MAX_32; /* 1 in Q31 */
+ Word32 rB_offset, reg_val;
+ Word32 ratio_prod;
+ Word16 n_reg_val;
+
+ if (M0 <= 0x7fff)
+ {
+ Word16 inv_M0 = Inv16_lc3plus(M0, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */
+ ratio = L_shr(Mpy_32_16_lc3plus(M1, inv_M0), 15 - ratio_exp); /* Integer ratio */
+ }
+ else
+ {
+ Word16 M0_h = L_shr(M0, 15);
+ Word32 M1_h = L_shr(M1, 15);
+
+ Word16 inv_M0 = Inv16_lc3plus(M0_h, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */
+ ratio = extract_l(L_shr(Mpy_32_16_lc3plus(M1_h, inv_M0), 15 - ratio_exp)); /* Integer ratio */
+ }
+
+ /*
+ regterm = MIN (M1 / M0, 2 *frame_ms) / (2 * frame_ms)
+ regterm = MIN (M1 * (10 / 2) / M0, frame_dms) / frame_dms
+ regterm = MIN ( ratio * 5, frame_dms) / frame_dms
+ */
+
+ ratio_prod = L_mult(ratio, 5);
+
+ if (ratio_prod < frame_dms)
+ {
+ Word16 mult_factor = 0;
+
+ SWITCH (frame_dms) /* 1 / frame_dms in Q15 */
+ {
+ case 25: mult_factor = 1311; break;
+ case 50: mult_factor = 655; break;
+#ifdef CR8_G_ADD_75MS
+ case 75: mult_factor = 437; break;
+#endif
+ case 100: mult_factor = 328; break;
+ }
+
+ /* ratio_prod < frame_dms. Hence Word16 can be used */
+
+ regterm = L_shl(L_mult(extract_l(ratio_prod), mult_factor), 15); /* result in Q31 */
+ }
+
+ rB_offset = L_sub(MAX_32, regterm);
+ /* Calculation in Q28 to prevent overflow. Subtraction result in Q31, downshift by 3 results in Q28.
+ Multiplication by 8 is implemented as upshift by 3.
+ */
+
+ /*
+ FLOAT code : reg_val = x_max * LC3_POW(2,-regBits - rB_offset);
+ */
+ Word16 reg_val_e = x_e;
+
+ IF(rB_offset > 0)
+ {
+ Word32 reg_exp = L_negate(L_add(L_shl(regBits, 25), L_shr(rB_offset, 3)));
+ reg_val = Mpy_32_32_lc3plus(x_max, BASOP_Util_InvLog2_lc3plus(reg_exp)); /* Product is in Q31 */
+ /* reg_val is in Q(31-x_e) */
+ }
+ ELSE
+ {
+ reg_val = x_max;
+ reg_val_e = sub(x_e, regBits);
+ }
+
+ sub_val = 0x183BA045;
+ move16();
+ /*28 * log10(32768*256 - 2) in Q21 */
+
+ /*
+ Adding LC3_POW(2, -31) to reg_val.2^-31 * 2^(31-x_e) = 2^-x_e.
+ If x_e is positive, this is below precision requirements to be used.
+ */
+
+ if (reg_val_e < 0)
+ {
+ reg_val = L_add_sat(reg_val, L_shl_sat(1, negate(reg_val_e)));
+ }
+ n_reg_val = norm_l(reg_val);
+
+ FOR (i = 0; i < lg_4; i++)
+ {
+ ener = en[i];
+ move16();
+ s = en_exp[i];
+ move16();
+
+ Word16 shift_val = sub(reg_val_e, s);
+
+ IF (sub(n_reg_val, shift_val) > 0)
+ {
+ IF(shift_val > -32)
+ {
+ ener = L_add(ener, L_shl(reg_val, shift_val)); /* Match q formats */
+ }
+ }
+ ELSE
+ {
+ IF (sub(shift_val, 32) >= 0 )
+ {
+ ener = reg_val;
+ }
+ ELSE
+ {
+ ener = L_add_sat(reg_val, L_shr(ener, shift_val));
+ }
+ s = reg_val_e;
+ }
+
+ tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */
+ tmp32 = L_add(L_shr_pos(Mpy_32_32_lc3plus(tmp32, 0x436E439A), 7), 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */
+ en[i] = tmp32;
+ move32();
+ }
+ }
+#endif
+ x_max = BASOP_Util_Log2_lc3plus(x_max);
+ /* Minimum gain */
+ x_max = L_add(x_max, L_shl_pos(L_deposit_l(x_e), 25)); /* log2(x_max) in 6Q25 */
+ x_max = L_sub(
+ Mpy_32_32_lc3plus(x_max, 0x436E439A),
+ sub_val); /* 28*log10(x_max/(32768-0.375)) = log2(x_max)*(28/log2(10))-28*log10(32768-0.375) in 10Q21 */
+ /* 28/log1(10) is in Q27
+ Mpy_32_32_lc3plus : Q25(x_max) + Q27 + Q1(Mpy_32_32_ss) - Q32 = Q21 */
+ *quantizedGainMin = extract_l(L_shr_pos(L_add(x_max, (1 << 21) + (1 << 11)), 21));
+ move16();
+ ASSERT(*quantizedGainMin <= 255 + quantizedGainOff);
+ *quantizedGainMin = s_max(quantizedGainOff, s_min(add(255, quantizedGainOff), *quantizedGainMin));
+
+ offset = L_deposit_h(add(255, quantizedGainOff)); /* -> 127 */
+
+#ifdef ENABLE_HR_MODE
+ IF(hrmode)
+ {
+ offset = L_shr_pos(offset, 2);
+ /* SQ scale: 4 bits / 6 dB per quadruple */
+ target = L_mult(0x3EB8, nbitsSQ); /* -> (28/20) * (1.4) * nbitsSQ */
+
+ fac = L_add(0x400000, 0); /* -> 256 */
+ /* find offset (0 to 127) */
+ FOR (iter = 0; iter < 8; iter++)
+ {
+ fac = L_shr_pos(fac, 1);
+ offset = L_sub(offset, fac);
+
+ ener = L_deposit_l(0);
+ iszero = 1;
+ move16();
+
+ FOR (i = lg_4 - 1; i >= 0; i--)
+ {
+ tmp32 = L_sub(L_shr_pos(en[i], 1), offset);
+ diff = L_sub(tmp32, 0x27333); /* 0x4E666 -> (28/20)*(7) in Q15 */
+ if (diff < 0)
+ {
+ if (iszero == 0)
+ {
+ ener = L_add(ener, 0xF1EC); /* 0x1E3D7 -> (28/20)*(2.7) in Q15 */
+ }
+ }
+ else
+ {
+ ener = L_add(ener, tmp32);
+ iszero = 0;
+ move16();
+
+ diff2 = L_sub(tmp32, 0x118000); /* 0x230000 -> (28/20)*(50) */
+ if (diff2 >= 0)
+ {
+ ener = L_add(ener, diff2);
+ }
+ }
+ }
+
+ /* if ener is above target -> increase offset */
+ test();
+ if (L_sub(ener, target) > 0 && iszero == 0)
+ {
+ offset = L_add(offset, fac);
+ }
+ }
+ tmp16 = extract_h(L_shl(offset, 2));
+ }
+ ELSE
+#endif
+ {
+ /* SQ scale: 4 bits / 6 dB per quadruple */
+ target = L_shl_pos(L_mult(0x7D71, nbitsSQ), 1); /* -> (28/20) * (1.4) * nbitsSQ */
+ fac = L_add(0x1000000, 0); /* -> 256 */
+
+ /* find offset (0 to 127) */
+ FOR (iter = 0; iter < 8; iter++)
+ {
+ fac = L_shr_pos(fac, 1);
+ offset = L_sub(offset, fac);
+
+ ener = L_deposit_l(0);
+ iszero = 1;
+ move16();
+ FOR (i = lg_4 - 1; i >= 0; i--)
+ {
+ tmp32 = L_sub(en[i], offset);
+ diff = L_sub(tmp32, 0x9CCCD); /* 0x9CCCD -> (28/20)*(7) in Q16 */
+ if (diff < 0)
+ {
+ if (iszero == 0)
+ {
+ ener = L_add_sat(ener, 0x3C7AE); /* 0x3C7AE -> (28/20)*(2.7) in Q16 */
+ }
+ }
+ else
+ {
+ ener = L_add_sat(ener, tmp32);
+ iszero = 0;
+ move16();
+
+ diff2 = L_sub(tmp32, 0x460000); /* 0x460000 -> (28/20)*(50) in Q16 */
+ if (diff2 >= 0)
+ {
+ ener = L_add_sat(ener, diff2);
+ }
+ }
+
+ }
+
+ /* if ener is above target -> increase offset */
+ test();
+ if (L_sub(ener, target) > 0 && iszero == 0)
+ {
+ offset = L_add(offset, fac);
+ }
+ }
+ tmp16 = extract_h(offset);
+
+ }
+
+ if (sub(tmp16, *quantizedGainMin) < 0)
+ {
+ *old_targetBits = -1;
+ move16();
+ }
+ *quantizedGain = sub(s_max(*quantizedGainMin, tmp16), quantizedGainOff);
+ move16();
+ }
+
+#ifdef ENABLE_HR_MODE
+ tmp32 =
+ Mpy_32_16_lc3plus(0x797CD707, L_shl_pos(add(*quantizedGain, quantizedGainOff), 6));
+#else
+ tmp32 =
+ L_shl_pos(L_mult0(add(*quantizedGain, quantizedGainOff), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
+#endif
+ *gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */
+#ifdef ENABLE_HR_MODE
+ *gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000));
+#else
+ *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32,(Word32) 0xFE000000)));
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/fft_lc3plus.c b/lib_lc3plus/fft_lc3plus.c
new file mode 100644
index 0000000000000000000000000000000000000000..a86286d0443572bf07c29297e245dab9b15768fb
--- /dev/null
+++ b/lib_lc3plus/fft_lc3plus.c
@@ -0,0 +1,4537 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "rom_basop_util.h"
+
+#ifdef ENABLE_FFT_RESCALE
+#ifndef FFT_RESCALE_HR
+#define FFT_RESCALE_HR 3
+#endif
+#endif
+
+#define SCALEFACTORN2 3
+#define SCALEFACTOR4 3
+#define SCALEFACTOR5 4
+#define SCALEFACTOR8 4
+#define SCALEFACTOR15 5
+#define SCALEFACTOR30_1 5
+#define SCALEFACTOR30_2 1
+#define SCALEFACTOR32_1 5
+#define SCALEFACTOR32_2 1
+
+#ifdef ENABLE_HR_MODE
+#define Mpy_32_xx Mpy_32_32_lc3plus
+#else
+#define Mpy_32_xx Mpy_32_16_lc3plus
+#endif
+
+#ifdef CR8_G_ADD_75MS
+#define SCALEFACTOR6 4
+#define C61_32 (0x6ed9eba1)
+#endif
+
+#define SCALEFACTOR10 5
+#define SCALEFACTOR16 5
+#define SCALEFACTOR20 5
+#define SCALEFACTOR30 6
+#define SCALEFACTOR32 6
+#define SCALEFACTOR40 7
+#define SCALEFACTOR48 8
+#define SCALEFACTOR60 7
+#define SCALEFACTOR64 7
+#define SCALEFACTOR80 8
+#define SCALEFACTOR90 9
+#define SCALEFACTOR96 9
+#define SCALEFACTOR120 8
+#define SCALEFACTOR128 8
+#define SCALEFACTOR160 8
+#define SCALEFACTOR180 10
+#define SCALEFACTOR192 10
+#define SCALEFACTOR240 9
+#define SCALEFACTOR256 9
+#define SCALEFACTOR384 11
+
+#ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+#define SCALEFACTOR360 11
+#endif
+#ifndef ENABLE_FFT_30X16
+#define SCALEFACTOR480 10
+#else
+#define SCALEFACTOR480 11
+#endif
+#endif
+
+#ifdef ENABLE_HR_MODE
+#undef L_shr_pos
+#define L_shr_pos(x, y) (L_shr(L_add(L_shr((x), ((y)-1)),1),1))
+#endif
+
+#ifdef ENABLE_HR_MODE
+#define FFTC(x) ((Word32)x)
+#else
+#define FFTC(x) WORD322WORD16((Word32)x)
+#endif
+
+#define C31 (FFTC(0x91261468)) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */
+
+#define C51 (FFTC(0x79bc3854)) /* FL2WORD32( 0.95105652) */
+#define C52 (FFTC(0x9d839db0)) /* FL2WORD32(-1.53884180/2) */
+#define C53 (FFTC(0xd18053ce)) /* FL2WORD32(-0.36327126) */
+#define C54 (FFTC(0x478dde64)) /* FL2WORD32( 0.55901699) */
+#define C55 (FFTC(0xb0000001)) /* FL2WORD32(-1.25/2) */
+
+#define C81 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) */
+#define C82 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) */
+
+#define C161 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) INV_SQRT2 */
+#define C162 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) -INV_SQRT2 */
+
+#define C163 (FFTC(0x7641af3d)) /* FL2WORD32( 9.238795325112867e-1) COS_PI_DIV8 */
+#define C164 (FFTC(0x89be50c3)) /* FL2WORD32(-9.238795325112867e-1) -COS_PI_DIV8 */
+
+#define C165 (FFTC(0x30fbc54d)) /* FL2WORD32( 3.826834323650898e-1) COS_3PI_DIV8 */
+#define C166 (FFTC(0xcf043ab3)) /* FL2WORD32(-3.826834323650898e-1) -COS_3PI_DIV8 */
+
+#define C51_32 (0x79bc3854) /* FL2WORD32( 0.95105652) */
+#define C52_32 (0x9d839db0) /* FL2WORD32(-1.53884180/2) */
+#define C53_32 (0xd18053ce) /* FL2WORD32(-0.36327126) */
+#define C54_32 (0x478dde64) /* FL2WORD32( 0.55901699) */
+#define C55_32 (0xb0000001) /* FL2WORD32(-1.25/2) */
+
+
+#define C81_32 (0x5a82799a) /* FL2WORD32( 7.071067811865475e-1) */
+#define C82_32 (0xa57d8666) /* FL2WORD32(-7.071067811865475e-1) */
+
+#if defined(ENABLE_HR_MODE)
+
+# define cplxMpy4_16_0(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \
+ move32(); \
+ im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \
+ move32(); \
+ } while (0)
+
+# define cplxMpy4_16_1(re, im, a, b) \
+ do \
+ { \
+ re = a; \
+ move32(); \
+ im = b; \
+ move32(); \
+ } while (0)
+
+# endif
+
+#define Mpy3_0(s12, s13, s14, s15, t0, t1, t2, t3) \
+ do \
+ { \
+ s12 = Mpy_32_32_lc3plus(L_add(t0, t2), C81_32); \
+ s14 = Mpy_32_32_lc3plus(L_sub(t0, t2), C81_32); \
+ s13 = Mpy_32_32_lc3plus(L_sub(t3, t1), C81_32); \
+ s15 = Mpy_32_32_lc3plus(L_add(t1, t3), C82_32); \
+ } while (0)
+
+#define cplxMpy3_0(a, b, c, d) \
+ do \
+ { \
+ as = L_shr_pos(a, 1); \
+ bs = L_shr_pos(b, 1); \
+ a = L_sub(Mpy_32_32_lc3plus(as, c), Mpy_32_32_lc3plus(bs, d)); \
+ b = L_add(Mpy_32_32_lc3plus(as, d), Mpy_32_32_lc3plus(bs, c)); \
+ } while (0)
+
+#ifdef ENABLE_HR_MODE
+#define cplxMpy4_4_0(re, im, a, b, c, d) \
+ re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \
+ im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15);
+
+# define cplxMpy4_4_1(re, im, a, b) \
+ re = L_shr_pos(a, SCALEFACTOR60 - SCALEFACTOR15); \
+ im = L_shr_pos(b, SCALEFACTOR60 - SCALEFACTOR15);
+#else
+#define cplxMpy4_4_0(re, im, a, b, c, d) \
+ re = L_shr(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \
+ im = L_shr(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15);
+
+#define cplxMpy4_4_1(re, im, a, b) \
+ re = L_shr(a, SCALEFACTOR60 - SCALEFACTOR15); \
+ im = L_shr(b, SCALEFACTOR60 - SCALEFACTOR15);
+#endif
+
+#define cplxMpy4_8_0(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), 1); \
+ im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), 1); \
+ } while (0)
+
+
+#define cplxMpy4_8_1(re, im, a, b) \
+ do \
+ { \
+ re = L_shr_pos(a, 1); \
+ im = L_shr_pos(b, 1); \
+ } while (0)
+
+
+#define cplxMpy4_8_2(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_shr_pos(L_add(Mpy_32_32_lc3plus(a, c), Mpy_32_32_lc3plus(b, d)), 1); \
+ im = L_shr_pos(L_sub(Mpy_32_32_lc3plus(b, c), Mpy_32_32_lc3plus(a, d)), 1); \
+ } while (0)
+
+
+#define cplxMpy4_12_0(re, im, a, b, c, d) \
+ do \
+ { \
+ re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \
+ move32(); \
+ im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \
+ move32(); \
+ } while (0)
+
+#define cplxMpy4_12_1(re, im, a, b) \
+ do \
+ { \
+ re = a; \
+ move32(); \
+ im = b; \
+ move32(); \
+ } while (0)
+
+
+static void fft4(Word32 *x)
+{
+ Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7;);
+
+ x0 = L_shr_pos(x[0], SCALEFACTOR4);
+ x1 = L_shr_pos(x[1], SCALEFACTOR4);
+ x2 = L_shr_pos(x[2], SCALEFACTOR4);
+ x3 = L_shr_pos(x[3], SCALEFACTOR4);
+ x4 = L_shr_pos(x[4], SCALEFACTOR4);
+ x5 = L_shr_pos(x[5], SCALEFACTOR4);
+ x6 = L_shr_pos(x[6], SCALEFACTOR4);
+ x7 = L_shr_pos(x[7], SCALEFACTOR4);
+
+ /* Pre-additions */
+ t0 = L_add(x0, x4);
+ t2 = L_sub(x0, x4);
+ t1 = L_add(x1, x5);
+ t3 = L_sub(x1, x5);
+ t4 = L_add(x2, x6);
+ t7 = L_sub(x2, x6);
+ t5 = L_add(x7, x3);
+ t6 = L_sub(x7, x3);
+
+ /* Post-additions */
+ x[0] = L_add(t0, t4);
+ x[1] = L_add(t1, t5);
+ x[2] = L_sub(t2, t6);
+ x[3] = L_sub(t3, t7);
+ x[4] = L_sub(t0, t4);
+ x[5] = L_sub(t1, t5);
+ x[6] = L_add(t2, t6);
+ x[7] = L_add(t3, t7);
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 5-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR5 bits.
+ *
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+
+static void fft5(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 t;);
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 0], SCALEFACTOR5);
+ x1 = L_shr_pos(re[s * 1], SCALEFACTOR5);
+ x2 = L_shr_pos(re[s * 2], SCALEFACTOR5);
+ x3 = L_shr_pos(re[s * 3], SCALEFACTOR5);
+ x4 = L_shr_pos(re[s * 4], SCALEFACTOR5);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x2, x3);
+ r2 = L_sub(x2, x3);
+ t = Mpy_32_32_lc3plus(L_sub(r1, r3), C54_32);
+ r1 = L_add(r1, r3);
+ re[0] = L_add(x0, r1);
+ move32();
+ /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of
+ the values as fracts */
+ r1 = L_add(re[0], (L_shl_pos(Mpy_32_32_lc3plus(r1, C55_32), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_32_lc3plus(L_add(r4, r2), C51_32);
+ /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of
+ the values as fracts */
+ r4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(r4, C52_32), 1));
+ r2 = L_add(t, Mpy_32_32_lc3plus(r2, C53_32));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 0], SCALEFACTOR5);
+ x1 = L_shr_pos(im[s * 1], SCALEFACTOR5);
+ x2 = L_shr_pos(im[s * 2], SCALEFACTOR5);
+ x3 = L_shr_pos(im[s * 3], SCALEFACTOR5);
+ x4 = L_shr_pos(im[s * 4], SCALEFACTOR5);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x2, x3);
+ s2 = L_sub(x2, x3);
+ t = Mpy_32_32_lc3plus(L_sub(s1, s3), C54_32);
+ s1 = L_add(s1, s3);
+ im[0] = L_add(x0, s1);
+ move32();
+ /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of
+ the values as fracts */
+ s1 = L_add(im[0], L_shl_pos(Mpy_32_32_lc3plus(s1, C55_32), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_32_lc3plus(L_add(s4, s2), C51_32);
+ /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of
+ the values as fracts */
+ s4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(s4, C52_32), 1));
+ s2 = L_add(t, Mpy_32_32_lc3plus(s2, C53_32));
+
+ /* combination */
+ re[s * 1] = L_add(r1, s2);
+ move32();
+ re[s * 4] = L_sub(r1, s2);
+ move32();
+ re[s * 2] = L_sub(r3, s4);
+ move32();
+ re[s * 3] = L_add(r3, s4);
+ move32();
+
+ im[s * 1] = L_sub(s1, r2);
+ move32();
+ im[s * 4] = L_add(s1, r2);
+ move32();
+ im[s * 2] = L_add(s3, r4);
+ move32();
+ im[s * 3] = L_sub(s3, r4);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 6-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR6 bits.
+ *
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] st stride real and imag input / output
+ *
+ * \return void
+ */
+
+#ifdef CR8_G_ADD_75MS
+static void fft6(Word32 *re, Word32 *im, Word16 st)
+{
+ Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5; Word32 r1o, r2o, i1e, i2e, i1o, i2o; Word32 t, s;);
+
+ /* process real parts */
+
+ x0 = L_shr_pos(re[0 * st], SCALEFACTOR6);
+ x1 = L_shr_pos(re[1 * st], SCALEFACTOR6);
+ x2 = L_shr_pos(re[2 * st], SCALEFACTOR6);
+ x3 = L_shr_pos(re[3 * st], SCALEFACTOR6);
+ x4 = L_shr_pos(re[4 * st], SCALEFACTOR6);
+ x5 = L_shr_pos(re[5 * st], SCALEFACTOR6);
+
+ t = L_add(x0, L_add(x2, x4));
+ s = L_add(x1, L_add(x3, x5));
+ re[0 * st] = L_add(t, s);
+ move32();
+ re[3 * st] = L_sub(t, s);
+ move32();
+ t = L_sub(x0, L_shr_pos(L_add(x2, x4), 1));
+
+ re[1 * st] = t;
+ move32();
+ re[2 * st] = t;
+ move32();
+ re[4 * st] = t;
+ move32();
+ re[5 * st] = t;
+ move32();
+
+ s = Mpy_32_32_lc3plus(L_sub(x4, x2), C61_32);
+
+ i1e = s;
+ i2e = -s;
+
+ t = L_sub(x1, L_shr_pos(L_add(x3, x5), 1));
+ s = Mpy_32_32_lc3plus(L_sub(x5, x3), C61_32);
+
+ r1o = r2o = t;
+ i1o = s;
+ i2o = -s;
+
+ x0 = L_shr_pos(im[0 * st], SCALEFACTOR6);
+ x1 = L_shr_pos(im[1 * st], SCALEFACTOR6);
+ x2 = L_shr_pos(im[2 * st], SCALEFACTOR6);
+ x3 = L_shr_pos(im[3 * st], SCALEFACTOR6);
+ x4 = L_shr_pos(im[4 * st], SCALEFACTOR6);
+ x5 = L_shr_pos(im[5 * st], SCALEFACTOR6);
+
+ t = L_add(x0, L_add(x2, x4));
+ s = L_add(x1, L_add(x3, x5));
+
+ im[0 * st] = L_add(t, s);
+ move32();
+ im[3 * st] = L_sub(t, s);
+ move32();
+
+ t = Mpy_32_32_lc3plus(L_sub(x2, x4), C61_32);
+ s = L_sub(x0, L_shr_pos(L_add(x2, x4), 1));
+
+ re[1 * st] = L_add(re[1 * st], t);
+ move32();
+ re[2 * st] = L_sub(re[2 * st], t);
+ move32();
+ re[4 * st] = L_add(re[4 * st], t);
+ move32();
+ re[5 * st] = L_sub(re[5 * st], t);
+ move32();
+
+ i1e = L_add(i1e, s);
+ i2e = L_add(i2e, s);
+
+ t = Mpy_32_32_lc3plus(L_sub(x3, x5), C61_32);
+ s = L_sub(x1, L_shr_pos(L_add(x5, x3), 1));
+
+ r1o = L_add(r1o, t);
+ r2o = L_sub(r2o, t);
+
+ i1o = L_add(i1o, s);
+ i2o = L_add(i2o, s);
+
+ t = L_add(L_shr_pos(r1o, 1), Mpy_32_32_lc3plus(i1o, C61_32));
+ s = L_sub(L_shr_pos(i1o, 1), Mpy_32_32_lc3plus(r1o, C61_32));
+
+ re[1 * st] = L_add(re[1 * st], t);
+ move32();
+ im[1 * st] = L_add(i1e, s);
+ move32();
+
+ re[4 * st] = L_sub(re[4 * st], t);
+ move32();
+ im[4 * st] = L_sub(i1e, s);
+ move32();
+
+ t = L_sub(Mpy_32_32_lc3plus(i2o, C61_32), L_shr_pos(r2o, 1));
+ s = L_negate(L_add(Mpy_32_32_lc3plus(r2o, C61_32), L_shr_pos(i2o, 1)));
+
+ re[2 * st] = L_add(re[2 * st], t);
+ move32();
+ im[2 * st] = L_add(i2e, s);
+ move32();
+
+ re[5 * st] = L_sub(re[5 * st], t);
+ move32();
+ im[5 * st] = L_sub(i2e, s);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+#endif
+
+/**
+ * \brief Function performs a complex 8-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR8 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 108 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+static void fft8(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 x00, x01, x02, x03, x04, x05, x06, x07; Word32 x08, x09, x10, x11, x12, x13, x14, x15;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07; Word32 t08, t09, t10, t11, t12, t13, t14, t15;
+ Word32 s00, s01, s02, s03, s04, s05, s06, s07; Word32 s08, s09, s10, s11, s12, s13, s14, s15;);
+
+ /* Pre-additions */
+
+ x00 = L_shr_pos(re[s * 0], SCALEFACTOR8);
+ x01 = L_shr_pos(im[s * 0], SCALEFACTOR8);
+ x02 = L_shr_pos(re[s * 1], SCALEFACTOR8);
+ x03 = L_shr_pos(im[s * 1], SCALEFACTOR8);
+ x04 = L_shr_pos(re[s * 2], SCALEFACTOR8);
+ x05 = L_shr_pos(im[s * 2], SCALEFACTOR8);
+ x06 = L_shr_pos(re[s * 3], SCALEFACTOR8);
+ x07 = L_shr_pos(im[s * 3], SCALEFACTOR8);
+ x08 = L_shr_pos(re[s * 4], SCALEFACTOR8);
+ x09 = L_shr_pos(im[s * 4], SCALEFACTOR8);
+ x10 = L_shr_pos(re[s * 5], SCALEFACTOR8);
+ x11 = L_shr_pos(im[s * 5], SCALEFACTOR8);
+ x12 = L_shr_pos(re[s * 6], SCALEFACTOR8);
+ x13 = L_shr_pos(im[s * 6], SCALEFACTOR8);
+ x14 = L_shr_pos(re[s * 7], SCALEFACTOR8);
+ x15 = L_shr_pos(im[s * 7], SCALEFACTOR8);
+
+ t00 = L_add(x00, x08);
+ t02 = L_sub(x00, x08);
+ t01 = L_add(x01, x09);
+ t03 = L_sub(x01, x09);
+ t04 = L_add(x02, x10);
+ t06 = L_sub(x02, x10);
+ t05 = L_add(x03, x11);
+ t07 = L_sub(x03, x11);
+ t08 = L_add(x04, x12);
+ t10 = L_sub(x04, x12);
+ t09 = L_add(x05, x13);
+ t11 = L_sub(x05, x13);
+ t12 = L_add(x06, x14);
+ t14 = L_sub(x06, x14);
+ t13 = L_add(x07, x15);
+ t15 = L_sub(x07, x15);
+
+ /* Pre-additions and core multiplications */
+
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+
+ t01 = L_add(t06, t14);
+ t02 = L_sub(t06, t14);
+ t00 = L_add(t07, t15);
+ t03 = L_sub(t07, t15);
+
+ s12 = Mpy_32_xx(L_add(t00, t02), C81);
+ s14 = Mpy_32_xx(L_sub(t00, t02), C81);
+ s13 = Mpy_32_xx(L_sub(t03, t01), C81);
+ s15 = Mpy_32_xx(L_add(t01, t03), C82);
+
+ /* Post-additions */
+
+ re[s * 0] = L_add(s00, s02);
+ move32();
+ re[s * 4] = L_sub(s00, s02);
+ move32();
+ im[s * 0] = L_add(s01, s03);
+ move32();
+ im[s * 4] = L_sub(s01, s03);
+ move32();
+ re[s * 2] = L_sub(s04, s06);
+ move32();
+ re[s * 6] = L_add(s04, s06);
+ move32();
+ im[s * 2] = L_sub(s05, s07);
+ move32();
+ im[s * 6] = L_add(s05, s07);
+ move32();
+ re[s * 3] = L_add(s08, s14);
+ move32();
+ re[s * 7] = L_sub(s08, s14);
+ move32();
+ im[s * 3] = L_add(s09, s15);
+ move32();
+ im[s * 7] = L_sub(s09, s15);
+ move32();
+ re[s * 1] = L_add(s10, s12);
+ move32();
+ re[s * 5] = L_sub(s10, s12);
+ move32();
+ im[s * 1] = L_add(s11, s13);
+ move32();
+ im[s * 5] = L_sub(s11, s13);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 10-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR10 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 196 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+
+static void fft10(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 t; Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4;
+ Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09;
+ Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;);
+
+ /* 2 fft5 stages */
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 0], SCALEFACTOR10);
+ x1 = L_shr_pos(re[s * 2], SCALEFACTOR10);
+ x2 = L_shr_pos(re[s * 4], SCALEFACTOR10);
+ x3 = L_shr_pos(re[s * 6], SCALEFACTOR10);
+ x4 = L_shr_pos(re[s * 8], SCALEFACTOR10);
+
+ r1 = L_add(x3, x2);
+ r4 = L_sub(x3, x2);
+ r3 = L_add(x1, x4);
+ r2 = L_sub(x1, x4);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y00 = L_add(x0, r1);
+ r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 0], SCALEFACTOR10);
+ x1 = L_shr_pos(im[s * 2], SCALEFACTOR10);
+ x2 = L_shr_pos(im[s * 4], SCALEFACTOR10);
+ x3 = L_shr_pos(im[s * 6], SCALEFACTOR10);
+ x4 = L_shr_pos(im[s * 8], SCALEFACTOR10);
+
+ s1 = L_add(x3, x2);
+ s4 = L_sub(x3, x2);
+ s3 = L_add(x1, x4);
+ s2 = L_sub(x1, x4);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y01 = L_add(x0, s1);
+ s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y04 = L_add(r1, s2);
+ y16 = L_sub(r1, s2);
+ y08 = L_sub(r3, s4);
+ y12 = L_add(r3, s4);
+
+ y05 = L_sub(s1, r2);
+ y17 = L_add(s1, r2);
+ y09 = L_add(s3, r4);
+ y13 = L_sub(s3, r4);
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 5], SCALEFACTOR10);
+ x1 = L_shr_pos(re[s * 1], SCALEFACTOR10);
+ x2 = L_shr_pos(re[s * 3], SCALEFACTOR10);
+ x3 = L_shr_pos(re[s * 7], SCALEFACTOR10);
+ x4 = L_shr_pos(re[s * 9], SCALEFACTOR10);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x3, x2);
+ r2 = L_sub(x3, x2);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y02 = L_add(x0, r1);
+ r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 5], SCALEFACTOR10);
+ x1 = L_shr_pos(im[s * 1], SCALEFACTOR10);
+ x2 = L_shr_pos(im[s * 3], SCALEFACTOR10);
+ x3 = L_shr_pos(im[s * 7], SCALEFACTOR10);
+ x4 = L_shr_pos(im[s * 9], SCALEFACTOR10);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x3, x2);
+ s2 = L_sub(x3, x2);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y03 = L_add(x0, s1);
+ s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y06 = L_add(r1, s2);
+ y18 = L_sub(r1, s2);
+ y10 = L_sub(r3, s4);
+ y14 = L_add(r3, s4);
+
+ y07 = L_sub(s1, r2);
+ y19 = L_add(s1, r2);
+ y11 = L_add(s3, r4);
+ y15 = L_sub(s3, r4);
+
+ /* 5 fft2 stages */
+ re[s * 0] = L_add(y00, y02);
+ move32();
+ im[s * 0] = L_add(y01, y03);
+ move32();
+ re[s * 5] = L_sub(y00, y02);
+ move32();
+ im[s * 5] = L_sub(y01, y03);
+ move32();
+
+ re[s * 2] = L_add(y04, y06);
+ move32();
+ im[s * 2] = L_add(y05, y07);
+ move32();
+ re[s * 7] = L_sub(y04, y06);
+ move32();
+ im[s * 7] = L_sub(y05, y07);
+ move32();
+
+ re[s * 4] = L_add(y08, y10);
+ move32();
+ im[s * 4] = L_add(y09, y11);
+ move32();
+ re[s * 9] = L_sub(y08, y10);
+ move32();
+ im[s * 9] = L_sub(y09, y11);
+ move32();
+
+ re[s * 6] = L_add(y12, y14);
+ move32();
+ im[s * 6] = L_add(y13, y15);
+ move32();
+ re[s * 1] = L_sub(y12, y14);
+ move32();
+ im[s * 1] = L_sub(y13, y15);
+ move32();
+
+ re[s * 8] = L_add(y16, y18);
+ move32();
+ im[s * 8] = L_add(y17, y19);
+ move32();
+ re[s * 3] = L_sub(y16, y18);
+ move32();
+ im[s * 3] = L_sub(y17, y19);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 15-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR15 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 354 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+static void fft15(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4;
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09;
+ Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19;
+ Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29;
+ Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09;
+ Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
+ Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;);
+
+ x00 = L_shr_pos(re[s * 0], SCALEFACTOR15);
+ x01 = L_shr_pos(im[s * 0], SCALEFACTOR15);
+ x02 = L_shr_pos(re[s * 3], SCALEFACTOR15);
+ x03 = L_shr_pos(im[s * 3], SCALEFACTOR15);
+ x04 = L_shr_pos(re[s * 6], SCALEFACTOR15);
+ x05 = L_shr_pos(im[s * 6], SCALEFACTOR15);
+ x06 = L_shr_pos(re[s * 9], SCALEFACTOR15);
+ x07 = L_shr_pos(im[s * 9], SCALEFACTOR15);
+ x08 = L_shr_pos(re[s * 12], SCALEFACTOR15);
+ x09 = L_shr_pos(im[s * 12], SCALEFACTOR15);
+
+ x10 = L_shr_pos(re[s * 5], SCALEFACTOR15);
+ x11 = L_shr_pos(im[s * 5], SCALEFACTOR15);
+ x12 = L_shr_pos(re[s * 8], SCALEFACTOR15);
+ x13 = L_shr_pos(im[s * 8], SCALEFACTOR15);
+ x14 = L_shr_pos(re[s * 11], SCALEFACTOR15);
+ x15 = L_shr_pos(im[s * 11], SCALEFACTOR15);
+ x16 = L_shr_pos(re[s * 14], SCALEFACTOR15);
+ x17 = L_shr_pos(im[s * 14], SCALEFACTOR15);
+ x18 = L_shr_pos(re[s * 2], SCALEFACTOR15);
+ x19 = L_shr_pos(im[s * 2], SCALEFACTOR15);
+
+ x20 = L_shr_pos(re[s * 10], SCALEFACTOR15);
+ x21 = L_shr_pos(im[s * 10], SCALEFACTOR15);
+ x22 = L_shr_pos(re[s * 13], SCALEFACTOR15);
+ x23 = L_shr_pos(im[s * 13], SCALEFACTOR15);
+ x24 = L_shr_pos(re[s * 1], SCALEFACTOR15);
+ x25 = L_shr_pos(im[s * 1], SCALEFACTOR15);
+ x26 = L_shr_pos(re[s * 4], SCALEFACTOR15);
+ x27 = L_shr_pos(im[s * 4], SCALEFACTOR15);
+ x28 = L_shr_pos(re[s * 7], SCALEFACTOR15);
+ x29 = L_shr_pos(im[s * 7], SCALEFACTOR15);
+
+ /* 1. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x02, x08);
+ r4 = L_sub(x02, x08);
+ r3 = L_add(x04, x06);
+ r2 = L_sub(x04, x06);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y00 = L_add(x00, r1);
+ r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x03, x09);
+ s4 = L_sub(x03, x09);
+ s3 = L_add(x05, x07);
+ s2 = L_sub(x05, x07);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y01 = L_add(x01, s1);
+ s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y02 = L_add(r1, s2);
+ y08 = L_sub(r1, s2);
+ y04 = L_sub(r3, s4);
+ y06 = L_add(r3, s4);
+
+ y03 = L_sub(s1, r2);
+ y09 = L_add(s1, r2);
+ y05 = L_add(s3, r4);
+ y07 = L_sub(s3, r4);
+
+ /* 2. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x12, x18);
+ r4 = L_sub(x12, x18);
+ r3 = L_add(x14, x16);
+ r2 = L_sub(x14, x16);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y10 = L_add(x10, r1);
+ r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x13, x19);
+ s4 = L_sub(x13, x19);
+ s3 = L_add(x15, x17);
+ s2 = L_sub(x15, x17);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y11 = L_add(x11, s1);
+ s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y12 = L_add(r1, s2);
+ y18 = L_sub(r1, s2);
+ y14 = L_sub(r3, s4);
+ y16 = L_add(r3, s4);
+
+ y13 = L_sub(s1, r2);
+ y19 = L_add(s1, r2);
+ y15 = L_add(s3, r4);
+ y17 = L_sub(s3, r4);
+
+ /* 3. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x22, x28);
+ r4 = L_sub(x22, x28);
+ r3 = L_add(x24, x26);
+ r2 = L_sub(x24, x26);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y20 = L_add(x20, r1);
+ r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x23, x29);
+ s4 = L_sub(x23, x29);
+ s3 = L_add(x25, x27);
+ s2 = L_sub(x25, x27);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y21 = L_add(x21, s1);
+ s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y22 = L_add(r1, s2);
+ y28 = L_sub(r1, s2);
+ y24 = L_sub(r3, s4);
+ y26 = L_add(r3, s4);
+
+ y23 = L_sub(s1, r2);
+ y29 = L_add(s1, r2);
+ y25 = L_add(s3, r4);
+ y27 = L_sub(s3, r4);
+
+ /* 1. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y10, y20);
+ r2 = Mpy_32_xx(L_sub(y10, y20), C31);
+ re[s * 0] = L_add(y00, r1);
+ move32();
+ r1 = L_sub(y00, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y11, y21);
+ s2 = Mpy_32_xx(L_sub(y11, y21), C31);
+ im[s * 0] = L_add(y01, s1);
+ move32();
+ s1 = L_sub(y01, L_shr_pos(s1, 1));
+
+ /* combination */
+ re[s * 10] = L_sub(r1, s2);
+ move32();
+ re[s * 5] = L_add(r1, s2);
+ move32();
+ im[s * 10] = L_add(s1, r2);
+ move32();
+ im[s * 5] = L_sub(s1, r2);
+ move32();
+
+ /* 2. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y12, y22);
+ r2 = Mpy_32_xx(L_sub(y12, y22), C31);
+ re[s * 6] = L_add(y02, r1);
+ move32();
+ r1 = L_sub(y02, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y13, y23);
+ s2 = Mpy_32_xx(L_sub(y13, y23), C31);
+ im[s * 6] = L_add(y03, s1);
+ move32();
+ s1 = L_sub(y03, L_shr_pos(s1, 1));
+
+ /* combination */
+ re[s * 1] = L_sub(r1, s2);
+ move32();
+ re[s * 11] = L_add(r1, s2);
+ move32();
+ im[s * 1] = L_add(s1, r2);
+ move32();
+ im[s * 11] = L_sub(s1, r2);
+ move32();
+
+ /* 3. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y14, y24);
+ r2 = Mpy_32_xx(L_sub(y14, y24), C31);
+ re[s * 12] = L_add(y04, r1);
+ move32();
+ r1 = L_sub(y04, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y15, y25);
+ s2 = Mpy_32_xx(L_sub(y15, y25), C31);
+ im[s * 12] = L_add(y05, s1);
+ move32();
+ s1 = L_sub(y05, L_shr_pos(s1, 1));
+
+ /* combination */
+ re[s * 7] = L_sub(r1, s2);
+ move32();
+ re[s * 2] = L_add(r1, s2);
+ move32();
+ im[s * 7] = L_add(s1, r2);
+ move32();
+ im[s * 2] = L_sub(s1, r2);
+ move32();
+
+ /* 4. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y16, y26);
+ r2 = Mpy_32_xx(L_sub(y16, y26), C31);
+ re[s * 3] = L_add(y06, r1);
+ move32();
+ r1 = L_sub(y06, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y17, y27);
+ s2 = Mpy_32_xx(L_sub(y17, y27), C31);
+ im[s * 3] = L_add(y07, s1);
+ move32();
+ s1 = L_sub(y07, L_shr_pos(s1, 1));
+
+ /* combination */
+ re[s * 13] = L_sub(r1, s2);
+ move32();
+ re[s * 8] = L_add(r1, s2);
+ move32();
+ im[s * 13] = L_add(s1, r2);
+ move32();
+ im[s * 8] = L_sub(s1, r2);
+ move32();
+
+ /* 5. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y18, y28);
+ r2 = Mpy_32_xx(L_sub(y18, y28), C31);
+ re[s * 9] = L_add(y08, r1);
+ move32();
+ r1 = L_sub(y08, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y19, y29);
+ s2 = Mpy_32_xx(L_sub(y19, y29), C31);
+ im[s * 9] = L_add(y09, s1);
+ move32();
+ s1 = L_sub(y09, L_shr_pos(s1, 1));
+
+ /* combination */
+ re[s * 4] = L_sub(r1, s2);
+ move32();
+ re[s * 14] = L_add(r1, s2);
+ move32();
+ im[s * 4] = L_add(s1, r2);
+ move32();
+ im[s * 14] = L_sub(s1, r2);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+#ifdef CR8_G_ADD_75MS
+
+#define STC(x) (x)
+const Word32 RotVectorReal12[] =
+{
+ STC(0x6ed9eba1), STC(0x40000000),
+ STC(0x40000000), STC(0xc0000000),
+#ifndef FFT12_UNROLLED_ENABLE
+ STC(0x00000000), STC(0x80000000),
+#endif
+};
+
+const Word32 RotVectorImag12[] =
+{
+ STC(0x40000000), STC(0x6ed9eba1),
+ STC(0x6ed9eba1), STC(0x6ed9eba1),
+#ifndef FFT12_UNROLLED_ENABLE
+ STC(0x7fffffff), STC(0x00000000),
+#endif
+};
+
+static void fft12(Word32 *pInput)
+{
+ Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im;
+ Word32 vre, vim;);
+
+ pSrc = pInput;
+ move16();
+ pDst = aDst;
+ move16();
+
+ /* First 3*2 samples are shifted right by 2 before output */
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+ pDst[2] = L_sub(r1, s2);
+ pDst[3] = L_add(s1, r2);
+ pDst[4] = L_add(r1, s2);
+ pDst[5] = L_sub(s1, r2);
+ pSrc += 2;
+ pDst += 6;
+
+ const Word32 *pVecRe = RotVectorReal12;
+ const Word32 *pVecIm = RotVectorImag12;
+
+
+
+ FOR (i = 0; i < 2; i++)
+ {
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */
+
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+ re = L_sub(r1, s2);
+ im = L_add(s1, r2);
+ vre = *pVecRe++;
+ vim = *pVecIm++;
+ cplxMpy_32_32(&pDst[3], &pDst[2], im, re, vre, vim);
+
+ re = L_add(r1, s2);
+ im = L_sub(s1, r2);
+
+ vre = *pVecRe++;
+ vim = *pVecIm++;
+ cplxMpy_32_32(&pDst[5], &pDst[4], im, re, vre, vim);
+
+ pDst += 6;
+ pSrc += 2;
+ }
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */
+ /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+
+ pDst[2] = L_add(s1, r2);
+ move32();
+ pDst[3] = L_sub(s2, r1);
+ move32();
+ pDst[4] = L_negate(L_add(r1, s2));
+ move32();
+ pDst[5] = L_sub(r2, s1);
+ move32();
+ /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the
+ output samples are at the address of pInput. The input vector for the fft of length 4 is built
+ of the interleaved samples in aDst, the output samples are stored consecutively at the address
+ of pInput.
+ */
+ move16();
+ move16();
+ pSrc = aDst;
+ pDst = pInput;
+ FOR (i = 0; i < 3; i++)
+ {
+ /* inline FFT4 merged with incoming resorting loop */
+ r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */
+ r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */
+ s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */
+ s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */
+
+ pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */
+ pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */
+
+ re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */
+ im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */
+
+ pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */
+ pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */
+
+ r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */
+ s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */
+
+ pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */
+ pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */
+ pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */
+ pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */
+
+ pSrc += 2;
+ pDst += 2;
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+#else /* CR8_G_ADD_75MS */
+
+static void fft12(Word32 *pInput)
+{
+ Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im;
+ Word16 vre, vim;);
+
+ pSrc = pInput;
+ move16();
+ pDst = aDst;
+ move16();
+
+ /* First 3*2 samples are shifted right by 2 before output */
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+ pDst[2] = L_sub(r1, s2);
+ pDst[3] = L_add(s1, r2);
+ pDst[4] = L_add(r1, s2);
+ pDst[5] = L_sub(s1, r2);
+ pSrc += 2;
+ pDst += 6;
+
+ vre = add(0x6eda, 0);
+ vim = add(0x4000, 0);
+
+ FOR (i = 0; i < 2; i++)
+ {
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */
+
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+ re = L_sub(r1, s2);
+ im = L_add(s1, r2);
+ cplxMpy_32_16(&pDst[3], &pDst[2], im, re, vre, vim);
+ re = L_add(r1, s2);
+ im = L_sub(s1, r2);
+ vre = add(0x4000, 0);
+ if (i == 1)
+ vre = negate(vre); /* 0xC000 */
+ if (i == 0)
+ vim = add(0x6eda, 0);
+ cplxMpy_32_16(&pDst[5], &pDst[4], im, re, vre, vim);
+
+ pDst += 6;
+ pSrc += 2;
+ }
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */
+ /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */
+ r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2));
+ r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31);
+ pD = L_shr_pos(pSrc[0], 2);
+ pDst[0] = L_shr_pos(L_add(pD, r1), 1);
+ r1 = L_sub(pD, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2));
+ s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31);
+ pD = L_shr_pos(pSrc[1], 2);
+ pDst[1] = L_shr_pos(L_add(pD, s1), 1);
+ s1 = L_sub(pD, L_shr_pos(s1, 1));
+
+ r1 = L_shr_pos(r1, 1);
+ r2 = L_shr_pos(r2, 1);
+ s1 = L_shr_pos(s1, 1);
+ s2 = L_shr_pos(s2, 1);
+
+ /* combination */
+
+ pDst[2] = L_add(s1, r2);
+ move32();
+ pDst[3] = L_sub(s2, r1);
+ move32();
+ pDst[4] = L_negate(L_add(r1, s2));
+ move32();
+ pDst[5] = L_sub(r2, s1);
+ move32();
+ /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the
+ output samples are at the address of pInput. The input vector for the fft of length 4 is built
+ of the interleaved samples in aDst, the output samples are stored consecutively at the address
+ of pInput.
+ */
+ move16();
+ move16();
+ pSrc = aDst;
+ pDst = pInput;
+ FOR (i = 0; i < 3; i++)
+ {
+ /* inline FFT4 merged with incoming resorting loop */
+ r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */
+ r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */
+ s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */
+ s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */
+
+ pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */
+ pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */
+
+ re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */
+ im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */
+
+ pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */
+ pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */
+
+ r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */
+ s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */
+
+ pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */
+ pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */
+ pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */
+ pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */
+
+ pSrc += 2;
+ pDst += 2;
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+#endif
+
+/**
+ * \brief Function performs a complex 16-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR16 bits.
+ *
+ * WOPS with 32x16 bit multiplications (scale on ): 288 cycles
+ * WOPS with 32x16 bit multiplications (scale off): 256 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+
+static void fft16(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7;
+ Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15;
+ Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31;);
+
+ x0 = L_shr_pos(re[s * 0], SCALEFACTOR16);
+ x1 = L_shr_pos(im[s * 0], SCALEFACTOR16);
+ x2 = L_shr_pos(re[s * 4], SCALEFACTOR16);
+ x3 = L_shr_pos(im[s * 4], SCALEFACTOR16);
+ x4 = L_shr_pos(re[s * 8], SCALEFACTOR16);
+ x5 = L_shr_pos(im[s * 8], SCALEFACTOR16);
+ x6 = L_shr_pos(re[s * 12], SCALEFACTOR16);
+ x7 = L_shr_pos(im[s * 12], SCALEFACTOR16);
+
+ /* Pre-additions */
+ t0 = L_add(x0, x4);
+ t2 = L_sub(x0, x4);
+ t1 = L_add(x1, x5);
+ t3 = L_sub(x1, x5);
+ t4 = L_add(x2, x6);
+ t7 = L_sub(x2, x6);
+ t5 = L_add(x7, x3);
+ t6 = L_sub(x7, x3);
+
+ /* Post-additions */
+ y00 = L_add(t0, t4);
+ y01 = L_add(t1, t5);
+ y02 = L_sub(t2, t6);
+ y03 = L_sub(t3, t7);
+ y04 = L_sub(t0, t4);
+ y05 = L_sub(t1, t5);
+ y06 = L_add(t2, t6);
+ y07 = L_add(t3, t7);
+
+ x0 = L_shr_pos(re[s * 1], SCALEFACTOR16);
+ x1 = L_shr_pos(im[s * 1], SCALEFACTOR16);
+ x2 = L_shr_pos(re[s * 5], SCALEFACTOR16);
+ x3 = L_shr_pos(im[s * 5], SCALEFACTOR16);
+ x4 = L_shr_pos(re[s * 9], SCALEFACTOR16);
+ x5 = L_shr_pos(im[s * 9], SCALEFACTOR16);
+ x6 = L_shr_pos(re[s * 13], SCALEFACTOR16);
+ x7 = L_shr_pos(im[s * 13], SCALEFACTOR16);
+
+ /* Pre-additions */
+ t0 = L_add(x0, x4);
+ t2 = L_sub(x0, x4);
+ t1 = L_add(x1, x5);
+ t3 = L_sub(x1, x5);
+ t4 = L_add(x2, x6);
+ t7 = L_sub(x2, x6);
+ t5 = L_add(x7, x3);
+ t6 = L_sub(x7, x3);
+
+ /* Post-additions */
+ y08 = L_add(t0, t4);
+ y09 = L_add(t1, t5);
+ y10 = L_sub(t2, t6);
+ y11 = L_sub(t3, t7);
+ y12 = L_sub(t0, t4);
+ y13 = L_sub(t1, t5);
+ y14 = L_add(t2, t6);
+ y15 = L_add(t3, t7);
+
+ x0 = L_shr_pos(re[s * 2], SCALEFACTOR16);
+ x1 = L_shr_pos(im[s * 2], SCALEFACTOR16);
+ x2 = L_shr_pos(re[s * 6], SCALEFACTOR16);
+ x3 = L_shr_pos(im[s * 6], SCALEFACTOR16);
+ x4 = L_shr_pos(re[s * 10], SCALEFACTOR16);
+ x5 = L_shr_pos(im[s * 10], SCALEFACTOR16);
+ x6 = L_shr_pos(re[s * 14], SCALEFACTOR16);
+ x7 = L_shr_pos(im[s * 14], SCALEFACTOR16);
+
+ /* Pre-additions */
+ t0 = L_add(x0, x4);
+ t2 = L_sub(x0, x4);
+ t1 = L_add(x1, x5);
+ t3 = L_sub(x1, x5);
+ t4 = L_add(x2, x6);
+ t7 = L_sub(x2, x6);
+ t5 = L_add(x7, x3);
+ t6 = L_sub(x7, x3);
+
+ /* Post-additions */
+ y16 = L_add(t0, t4);
+ y17 = L_add(t1, t5);
+ y18 = L_sub(t2, t6);
+ y19 = L_sub(t3, t7);
+ y20 = L_sub(t1, t5);
+ y21 = L_sub(t4, t0);
+ y22 = L_add(t2, t6);
+ y23 = L_add(t3, t7);
+
+ x0 = L_shr_pos(re[s * 3], SCALEFACTOR16);
+ x1 = L_shr_pos(im[s * 3], SCALEFACTOR16);
+ x2 = L_shr_pos(re[s * 7], SCALEFACTOR16);
+ x3 = L_shr_pos(im[s * 7], SCALEFACTOR16);
+ x4 = L_shr_pos(re[s * 11], SCALEFACTOR16);
+ x5 = L_shr_pos(im[s * 11], SCALEFACTOR16);
+ x6 = L_shr_pos(re[s * 15], SCALEFACTOR16);
+ x7 = L_shr_pos(im[s * 15], SCALEFACTOR16);
+
+ /* Pre-additions */
+ t0 = L_add(x0, x4);
+ t2 = L_sub(x0, x4);
+ t1 = L_add(x1, x5);
+ t3 = L_sub(x1, x5);
+ t4 = L_add(x2, x6);
+ t7 = L_sub(x2, x6);
+ t5 = L_add(x7, x3);
+ t6 = L_sub(x7, x3);
+
+ /* Post-additions */
+ y24 = L_add(t0, t4);
+ y25 = L_add(t1, t5);
+ y26 = L_sub(t2, t6);
+ y27 = L_sub(t3, t7);
+ y28 = L_sub(t0, t4);
+ y29 = L_sub(t1, t5);
+ y30 = L_add(t2, t6);
+ y31 = L_add(t3, t7);
+
+ /* rotation */
+
+ x0 = Mpy_32_xx(y22, C162);
+ x1 = Mpy_32_xx(y23, C162);
+ y22 = L_sub(x0, x1);
+ y23 = L_add(x0, x1);
+
+ x0 = Mpy_32_xx(y28, C162);
+ x1 = Mpy_32_xx(y29, C162);
+ y28 = L_sub(x0, x1);
+ y29 = L_add(x0, x1);
+
+ x0 = Mpy_32_xx(y12, C161);
+ x1 = Mpy_32_xx(y13, C161);
+ y12 = L_add(x0, x1);
+ y13 = L_sub(x1, x0);
+
+ x0 = Mpy_32_xx(y18, C161);
+ x1 = Mpy_32_xx(y19, C161);
+ y18 = L_add(x0, x1);
+ y19 = L_sub(x1, x0);
+
+ x0 = Mpy_32_xx(y10, C163);
+ x1 = Mpy_32_xx(y11, C166);
+ x2 = Mpy_32_xx(y10, C166);
+ x3 = Mpy_32_xx(y11, C163);
+ y10 = L_sub(x0, x1);
+ y11 = L_add(x2, x3);
+
+ x0 = Mpy_32_xx(y14, C165);
+ x1 = Mpy_32_xx(y15, C164);
+ x2 = Mpy_32_xx(y14, C164);
+ x3 = Mpy_32_xx(y15, C165);
+ y14 = L_sub(x0, x1);
+ y15 = L_add(x2, x3);
+
+ x0 = Mpy_32_xx(y26, C165);
+ x1 = Mpy_32_xx(y27, C164);
+ x2 = Mpy_32_xx(y26, C164);
+ x3 = Mpy_32_xx(y27, C165);
+ y26 = L_sub(x0, x1);
+ y27 = L_add(x2, x3);
+
+ x0 = Mpy_32_xx(y30, C164);
+ x1 = Mpy_32_xx(y31, C165);
+ x2 = Mpy_32_xx(y30, C165);
+ x3 = Mpy_32_xx(y31, C164);
+ y30 = L_sub(x0, x1);
+ y31 = L_add(x2, x3);
+
+ /* Pre-additions */
+
+ t0 = L_add(y00, y16);
+ t2 = L_sub(y00, y16);
+ t1 = L_add(y01, y17);
+ t3 = L_sub(y01, y17);
+ t4 = L_add(y08, y24);
+ t7 = L_sub(y08, y24);
+ t5 = L_add(y25, y09);
+ t6 = L_sub(y25, y09);
+
+ /* Post-additions */
+
+ re[s * 0] = L_add(t0, t4);
+ move32();
+ im[s * 0] = L_add(t1, t5);
+ move32();
+ re[s * 4] = L_sub(t2, t6);
+ move32();
+ im[s * 4] = L_sub(t3, t7);
+ move32();
+ re[s * 8] = L_sub(t0, t4);
+ move32();
+ im[s * 8] = L_sub(t1, t5);
+ move32();
+ re[s * 12] = L_add(t2, t6);
+ move32();
+ im[s * 12] = L_add(t3, t7);
+ move32();
+
+ /* Pre-additions */
+
+ t0 = L_add(y02, y18);
+ t2 = L_sub(y02, y18);
+ t1 = L_add(y03, y19);
+ t3 = L_sub(y03, y19);
+ t4 = L_add(y10, y26);
+ t7 = L_sub(y10, y26);
+ t5 = L_add(y27, y11);
+ t6 = L_sub(y27, y11);
+
+ /* Post-additions */
+
+ re[s * 1] = L_add(t0, t4);
+ move32();
+ im[s * 1] = L_add(t1, t5);
+ move32();
+ re[s * 5] = L_sub(t2, t6);
+ move32();
+ im[s * 5] = L_sub(t3, t7);
+ move32();
+ re[s * 9] = L_sub(t0, t4);
+ move32();
+ im[s * 9] = L_sub(t1, t5);
+ move32();
+ re[s * 13] = L_add(t2, t6);
+ move32();
+ im[s * 13] = L_add(t3, t7);
+ move32();
+
+ /* Pre-additions */
+
+ t0 = L_add(y04, y20);
+ t2 = L_sub(y04, y20);
+ t1 = L_add(y05, y21);
+ t3 = L_sub(y05, y21);
+ t4 = L_add(y12, y28);
+ t7 = L_sub(y12, y28);
+ t5 = L_add(y29, y13);
+ t6 = L_sub(y29, y13);
+
+ /* Post-additions */
+
+ re[s * 2] = L_add(t0, t4);
+ move32();
+ im[s * 2] = L_add(t1, t5);
+ move32();
+ re[s * 6] = L_sub(t2, t6);
+ move32();
+ im[s * 6] = L_sub(t3, t7);
+ move32();
+ re[s * 10] = L_sub(t0, t4);
+ move32();
+ im[s * 10] = L_sub(t1, t5);
+ move32();
+ re[s * 14] = L_add(t2, t6);
+ move32();
+ im[s * 14] = L_add(t3, t7);
+ move32();
+
+ /* Pre-additions */
+
+ t0 = L_add(y06, y22);
+ t2 = L_sub(y06, y22);
+ t1 = L_add(y07, y23);
+ t3 = L_sub(y07, y23);
+ t4 = L_add(y14, y30);
+ t7 = L_sub(y14, y30);
+ t5 = L_add(y31, y15);
+ t6 = L_sub(y31, y15);
+
+ /* Post-additions */
+
+ re[s * 3] = L_add(t0, t4);
+ move32();
+ im[s * 3] = L_add(t1, t5);
+ move32();
+ re[s * 7] = L_sub(t2, t6);
+ move32();
+ im[s * 7] = L_sub(t3, t7);
+ move32();
+ re[s * 11] = L_sub(t0, t4);
+ move32();
+ im[s * 11] = L_sub(t1, t5);
+ move32();
+ re[s * 15] = L_add(t2, t6);
+ move32();
+ im[s * 15] = L_add(t3, t7);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 20-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR20 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 432 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+static void fft20(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 x0, x1, x2, x3, x4;
+ Word32 t, t0, t1, t2, t3, t4, t5, t6, t7; Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09;
+ Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
+ Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;
+ Word32 y30, y31, y32, y33, y34, y35, y36, y37, y38, y39;);
+
+ /* 1. FFT5 stage */
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 0], SCALEFACTOR20);
+ x1 = L_shr_pos(re[s * 16], SCALEFACTOR20);
+ x2 = L_shr_pos(re[s * 12], SCALEFACTOR20);
+ x3 = L_shr_pos(re[s * 8], SCALEFACTOR20);
+ x4 = L_shr_pos(re[s * 4], SCALEFACTOR20);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x2, x3);
+ r2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y00 = L_add(x0, r1);
+ r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 0], SCALEFACTOR20);
+ x1 = L_shr_pos(im[s * 16], SCALEFACTOR20);
+ x2 = L_shr_pos(im[s * 12], SCALEFACTOR20);
+ x3 = L_shr_pos(im[s * 8], SCALEFACTOR20);
+ x4 = L_shr_pos(im[s * 4], SCALEFACTOR20);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x2, x3);
+ s2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y01 = L_add(x0, s1);
+ s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y08 = L_add(r1, s2);
+ y32 = L_sub(r1, s2);
+ y16 = L_sub(r3, s4);
+ y24 = L_add(r3, s4);
+
+ y09 = L_sub(s1, r2);
+ y33 = L_add(s1, r2);
+ y17 = L_add(s3, r4);
+ y25 = L_sub(s3, r4);
+
+ /* 2. FFT5 stage */
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 5], SCALEFACTOR20);
+ x1 = L_shr_pos(re[s * 1], SCALEFACTOR20);
+ x2 = L_shr_pos(re[s * 17], SCALEFACTOR20);
+ x3 = L_shr_pos(re[s * 13], SCALEFACTOR20);
+ x4 = L_shr_pos(re[s * 9], SCALEFACTOR20);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x2, x3);
+ r2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y02 = L_add(x0, r1);
+ r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 5], SCALEFACTOR20);
+ x1 = L_shr_pos(im[s * 1], SCALEFACTOR20);
+ x2 = L_shr_pos(im[s * 17], SCALEFACTOR20);
+ x3 = L_shr_pos(im[s * 13], SCALEFACTOR20);
+ x4 = L_shr_pos(im[s * 9], SCALEFACTOR20);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x2, x3);
+ s2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y03 = L_add(x0, s1);
+ s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y10 = L_add(r1, s2);
+ y34 = L_sub(r1, s2);
+ y18 = L_sub(r3, s4);
+ y26 = L_add(r3, s4);
+
+ y11 = L_sub(s1, r2);
+ y35 = L_add(s1, r2);
+ y19 = L_add(s3, r4);
+ y27 = L_sub(s3, r4);
+
+ /* 3. FFT5 stage */
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 10], SCALEFACTOR20);
+ x1 = L_shr_pos(re[s * 6], SCALEFACTOR20);
+ x2 = L_shr_pos(re[s * 2], SCALEFACTOR20);
+ x3 = L_shr_pos(re[s * 18], SCALEFACTOR20);
+ x4 = L_shr_pos(re[s * 14], SCALEFACTOR20);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x2, x3);
+ r2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y04 = L_add(x0, r1);
+ r1 = L_add(y04, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 10], SCALEFACTOR20);
+ x1 = L_shr_pos(im[s * 6], SCALEFACTOR20);
+ x2 = L_shr_pos(im[s * 2], SCALEFACTOR20);
+ x3 = L_shr_pos(im[s * 18], SCALEFACTOR20);
+ x4 = L_shr_pos(im[s * 14], SCALEFACTOR20);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x2, x3);
+ s2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y05 = L_add(x0, s1);
+ s1 = L_add(y05, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y12 = L_add(r1, s2);
+ y36 = L_sub(r1, s2);
+ y20 = L_sub(r3, s4);
+ y28 = L_add(r3, s4);
+
+ y13 = L_sub(s1, r2);
+ y37 = L_add(s1, r2);
+ y21 = L_add(s3, r4);
+ y29 = L_sub(s3, r4);
+
+ /* 4. FFT5 stage */
+
+ /* real part */
+ x0 = L_shr_pos(re[s * 15], SCALEFACTOR20);
+ x1 = L_shr_pos(re[s * 11], SCALEFACTOR20);
+ x2 = L_shr_pos(re[s * 7], SCALEFACTOR20);
+ x3 = L_shr_pos(re[s * 3], SCALEFACTOR20);
+ x4 = L_shr_pos(re[s * 19], SCALEFACTOR20);
+
+ r1 = L_add(x1, x4);
+ r4 = L_sub(x1, x4);
+ r3 = L_add(x2, x3);
+ r2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y06 = L_add(x0, r1);
+ r1 = L_add(y06, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ x0 = L_shr_pos(im[s * 15], SCALEFACTOR20);
+ x1 = L_shr_pos(im[s * 11], SCALEFACTOR20);
+ x2 = L_shr_pos(im[s * 7], SCALEFACTOR20);
+ x3 = L_shr_pos(im[s * 3], SCALEFACTOR20);
+ x4 = L_shr_pos(im[s * 19], SCALEFACTOR20);
+
+ s1 = L_add(x1, x4);
+ s4 = L_sub(x1, x4);
+ s3 = L_add(x2, x3);
+ s2 = L_sub(x2, x3);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y07 = L_add(x0, s1);
+ s1 = L_add(y07, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y14 = L_add(r1, s2);
+ y38 = L_sub(r1, s2);
+ y22 = L_sub(r3, s4);
+ y30 = L_add(r3, s4);
+
+ y15 = L_sub(s1, r2);
+ y39 = L_add(s1, r2);
+ y23 = L_add(s3, r4);
+ y31 = L_sub(s3, r4);
+
+ /* 1. FFT4 stage */
+
+ /* Pre-additions */
+ t0 = L_add(y00, y04);
+ t2 = L_sub(y00, y04);
+ t1 = L_add(y01, y05);
+ t3 = L_sub(y01, y05);
+ t4 = L_add(y02, y06);
+ t7 = L_sub(y02, y06);
+ t5 = L_add(y07, y03);
+ t6 = L_sub(y07, y03);
+
+ /* Post-additions */
+ re[s * 0] = L_add(t0, t4);
+ move32();
+ im[s * 0] = L_add(t1, t5);
+ move32();
+ re[s * 5] = L_sub(t2, t6);
+ move32();
+ im[s * 5] = L_sub(t3, t7);
+ move32();
+ re[s * 10] = L_sub(t0, t4);
+ move32();
+ im[s * 10] = L_sub(t1, t5);
+ move32();
+ re[s * 15] = L_add(t2, t6);
+ move32();
+ im[s * 15] = L_add(t3, t7);
+ move32();
+
+ /* 2. FFT4 stage */
+
+ /* Pre-additions */
+ t0 = L_add(y08, y12);
+ t2 = L_sub(y08, y12);
+ t1 = L_add(y09, y13);
+ t3 = L_sub(y09, y13);
+ t4 = L_add(y10, y14);
+ t7 = L_sub(y10, y14);
+ t5 = L_add(y15, y11);
+ t6 = L_sub(y15, y11);
+
+ /* Post-additions */
+ re[s * 4] = L_add(t0, t4);
+ move32();
+ im[s * 4] = L_add(t1, t5);
+ move32();
+ re[s * 9] = L_sub(t2, t6);
+ move32();
+ im[s * 9] = L_sub(t3, t7);
+ move32();
+ re[s * 14] = L_sub(t0, t4);
+ move32();
+ im[s * 14] = L_sub(t1, t5);
+ move32();
+ re[s * 19] = L_add(t2, t6);
+ move32();
+ im[s * 19] = L_add(t3, t7);
+ move32();
+
+ /* 3. FFT4 stage */
+
+ /* Pre-additions */
+ t0 = L_add(y16, y20);
+ t2 = L_sub(y16, y20);
+ t1 = L_add(y17, y21);
+ t3 = L_sub(y17, y21);
+ t4 = L_add(y18, y22);
+ t7 = L_sub(y18, y22);
+ t5 = L_add(y23, y19);
+ t6 = L_sub(y23, y19);
+
+ /* Post-additions */
+ re[s * 8] = L_add(t0, t4);
+ move32();
+ im[s * 8] = L_add(t1, t5);
+ move32();
+ re[s * 13] = L_sub(t2, t6);
+ move32();
+ im[s * 13] = L_sub(t3, t7);
+ move32();
+ re[s * 18] = L_sub(t0, t4);
+ move32();
+ im[s * 18] = L_sub(t1, t5);
+ move32();
+ re[s * 3] = L_add(t2, t6);
+ move32();
+ im[s * 3] = L_add(t3, t7);
+ move32();
+
+ /* 4. FFT4 stage */
+
+ /* Pre-additions */
+ t0 = L_add(y24, y28);
+ t2 = L_sub(y24, y28);
+ t1 = L_add(y25, y29);
+ t3 = L_sub(y25, y29);
+ t4 = L_add(y26, y30);
+ t7 = L_sub(y26, y30);
+ t5 = L_add(y31, y27);
+ t6 = L_sub(y31, y27);
+
+ /* Post-additions */
+ re[s * 12] = L_add(t0, t4);
+ move32();
+ im[s * 12] = L_add(t1, t5);
+ move32();
+ re[s * 17] = L_sub(t2, t6);
+ move32();
+ im[s * 17] = L_sub(t3, t7);
+ move32();
+ re[s * 2] = L_sub(t0, t4);
+ move32();
+ im[s * 2] = L_sub(t1, t5);
+ move32();
+ re[s * 7] = L_add(t2, t6);
+ move32();
+ im[s * 7] = L_add(t3, t7);
+ move32();
+
+ /* 5. FFT4 stage */
+
+ /* Pre-additions */
+ t0 = L_add(y32, y36);
+ t2 = L_sub(y32, y36);
+ t1 = L_add(y33, y37);
+ t3 = L_sub(y33, y37);
+ t4 = L_add(y34, y38);
+ t7 = L_sub(y34, y38);
+ t5 = L_add(y39, y35);
+ t6 = L_sub(y39, y35);
+
+ /* Post-additions */
+ re[s * 16] = L_add(t0, t4);
+ move32();
+ im[s * 16] = L_add(t1, t5);
+ move32();
+ re[s * 1] = L_sub(t2, t6);
+ move32();
+ im[s * 1] = L_sub(t3, t7);
+ move32();
+ re[s * 6] = L_sub(t0, t4);
+ move32();
+ im[s * 6] = L_sub(t1, t5);
+ move32();
+ re[s * 11] = L_add(t2, t6);
+ move32();
+ im[s * 11] = L_add(t3, t7);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 30-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR30 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 828 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+static void fft30(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4;
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09;
+ Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19;
+ Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29;
+
+ Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09;
+ Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
+ Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;
+
+ Word32 z00, z01, z02, z03, z04, z05, z06, z07, z08, z09;
+ Word32 z10, z11, z12, z13, z14, z15, z16, z17, z18, z19;
+ Word32 z20, z21, z22, z23, z24, z25, z26, z27, z28, z29;
+ Word32 z30, z31, z32, z33, z34, z35, z36, z37, z38, z39;
+ Word32 z40, z41, z42, z43, z44, z45, z46, z47, z48, z49;
+ Word32 z50, z51, z52, z53, z54, z55, z56, z57, z58, z59;
+
+ Word32 * rel, *reh, *iml, *imh;);
+
+ rel = &re[s * 0];
+ reh = &re[s * 15];
+ iml = &im[s * 0];
+ imh = &im[s * 15];
+
+ /* 1. FFT15 stage */
+ x00 = L_shr_pos(re[s * 0], SCALEFACTOR30_1);
+ x01 = L_shr_pos(im[s * 0], SCALEFACTOR30_1);
+ x02 = L_shr_pos(re[s * 18], SCALEFACTOR30_1);
+ x03 = L_shr_pos(im[s * 18], SCALEFACTOR30_1);
+ x04 = L_shr_pos(re[s * 6], SCALEFACTOR30_1);
+ x05 = L_shr_pos(im[s * 6], SCALEFACTOR30_1);
+ x06 = L_shr_pos(re[s * 24], SCALEFACTOR30_1);
+ x07 = L_shr_pos(im[s * 24], SCALEFACTOR30_1);
+ x08 = L_shr_pos(re[s * 12], SCALEFACTOR30_1);
+ x09 = L_shr_pos(im[s * 12], SCALEFACTOR30_1);
+
+ x10 = L_shr_pos(re[s * 20], SCALEFACTOR30_1);
+ x11 = L_shr_pos(im[s * 20], SCALEFACTOR30_1);
+ x12 = L_shr_pos(re[s * 8], SCALEFACTOR30_1);
+ x13 = L_shr_pos(im[s * 8], SCALEFACTOR30_1);
+ x14 = L_shr_pos(re[s * 26], SCALEFACTOR30_1);
+ x15 = L_shr_pos(im[s * 26], SCALEFACTOR30_1);
+ x16 = L_shr_pos(re[s * 14], SCALEFACTOR30_1);
+ x17 = L_shr_pos(im[s * 14], SCALEFACTOR30_1);
+ x18 = L_shr_pos(re[s * 2], SCALEFACTOR30_1);
+ x19 = L_shr_pos(im[s * 2], SCALEFACTOR30_1);
+
+ x20 = L_shr_pos(re[s * 10], SCALEFACTOR30_1);
+ x21 = L_shr_pos(im[s * 10], SCALEFACTOR30_1);
+ x22 = L_shr_pos(re[s * 28], SCALEFACTOR30_1);
+ x23 = L_shr_pos(im[s * 28], SCALEFACTOR30_1);
+ x24 = L_shr_pos(re[s * 16], SCALEFACTOR30_1);
+ x25 = L_shr_pos(im[s * 16], SCALEFACTOR30_1);
+ x26 = L_shr_pos(re[s * 4], SCALEFACTOR30_1);
+ x27 = L_shr_pos(im[s * 4], SCALEFACTOR30_1);
+ x28 = L_shr_pos(re[s * 22], SCALEFACTOR30_1);
+ x29 = L_shr_pos(im[s * 22], SCALEFACTOR30_1);
+
+ /* 1. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x02, x08);
+ r4 = L_sub(x02, x08);
+ r3 = L_add(x04, x06);
+ r2 = L_sub(x04, x06);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y00 = L_add(x00, r1);
+ r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x03, x09);
+ s4 = L_sub(x03, x09);
+ s3 = L_add(x05, x07);
+ s2 = L_sub(x05, x07);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y01 = L_add(x01, s1);
+ s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y02 = L_add(r1, s2);
+ y08 = L_sub(r1, s2);
+ y04 = L_sub(r3, s4);
+ y06 = L_add(r3, s4);
+
+ y03 = L_sub(s1, r2);
+ y09 = L_add(s1, r2);
+ y05 = L_add(s3, r4);
+ y07 = L_sub(s3, r4);
+
+ /* 2. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x12, x18);
+ r4 = L_sub(x12, x18);
+ r3 = L_add(x14, x16);
+ r2 = L_sub(x14, x16);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y10 = L_add(x10, r1);
+ r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x13, x19);
+ s4 = L_sub(x13, x19);
+ s3 = L_add(x15, x17);
+ s2 = L_sub(x15, x17);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y11 = L_add(x11, s1);
+ s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y12 = L_add(r1, s2);
+ y18 = L_sub(r1, s2);
+ y14 = L_sub(r3, s4);
+ y16 = L_add(r3, s4);
+
+ y13 = L_sub(s1, r2);
+ y19 = L_add(s1, r2);
+ y15 = L_add(s3, r4);
+ y17 = L_sub(s3, r4);
+
+ /* 3. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x22, x28);
+ r4 = L_sub(x22, x28);
+ r3 = L_add(x24, x26);
+ r2 = L_sub(x24, x26);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y20 = L_add(x20, r1);
+ r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x23, x29);
+ s4 = L_sub(x23, x29);
+ s3 = L_add(x25, x27);
+ s2 = L_sub(x25, x27);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y21 = L_add(x21, s1);
+ s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y22 = L_add(r1, s2);
+ y28 = L_sub(r1, s2);
+ y24 = L_sub(r3, s4);
+ y26 = L_add(r3, s4);
+
+ y23 = L_sub(s1, r2);
+ y29 = L_add(s1, r2);
+ y25 = L_add(s3, r4);
+ y27 = L_sub(s3, r4);
+
+ /* 1. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y10, y20);
+ r2 = Mpy_32_xx(L_sub(y10, y20), C31);
+ z00 = L_add(y00, r1);
+ r1 = L_sub(y00, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y11, y21);
+ s2 = Mpy_32_xx(L_sub(y11, y21), C31);
+ z01 = L_add(y01, s1);
+ s1 = L_sub(y01, L_shr_pos(s1, 1));
+
+ /* combination */
+ z20 = L_sub(r1, s2);
+ z10 = L_add(r1, s2);
+ z21 = L_add(s1, r2);
+ z11 = L_sub(s1, r2);
+
+ /* 2. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y12, y22);
+ r2 = Mpy_32_xx(L_sub(y12, y22), C31);
+ z12 = L_add(y02, r1);
+ r1 = L_sub(y02, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y13, y23);
+ s2 = Mpy_32_xx(L_sub(y13, y23), C31);
+ z13 = L_add(y03, s1);
+ s1 = L_sub(y03, L_shr_pos(s1, 1));
+
+ /* combination */
+ z02 = L_sub(r1, s2);
+ z22 = L_add(r1, s2);
+ z03 = L_add(s1, r2);
+ z23 = L_sub(s1, r2);
+
+ /* 3. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y14, y24);
+ r2 = Mpy_32_xx(L_sub(y14, y24), C31);
+ z24 = L_add(y04, r1);
+ r1 = L_sub(y04, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y15, y25);
+ s2 = Mpy_32_xx(L_sub(y15, y25), C31);
+ z25 = L_add(y05, s1);
+ s1 = L_sub(y05, L_shr_pos(s1, 1));
+
+ /* combination */
+ z14 = L_sub(r1, s2);
+ z04 = L_add(r1, s2);
+ z15 = L_add(s1, r2);
+ z05 = L_sub(s1, r2);
+
+ /* 4. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y16, y26);
+ r2 = Mpy_32_xx(L_sub(y16, y26), C31);
+ z06 = L_add(y06, r1);
+ r1 = L_sub(y06, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y17, y27);
+ s2 = Mpy_32_xx(L_sub(y17, y27), C31);
+ z07 = L_add(y07, s1);
+ s1 = L_sub(y07, L_shr_pos(s1, 1));
+
+ /* combination */
+ z26 = L_sub(r1, s2);
+ z16 = L_add(r1, s2);
+ z27 = L_add(s1, r2);
+ z17 = L_sub(s1, r2);
+
+ /* 5. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y18, y28);
+ r2 = Mpy_32_xx(L_sub(y18, y28), C31);
+ z18 = L_add(y08, r1);
+ r1 = L_sub(y08, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y19, y29);
+ s2 = Mpy_32_xx(L_sub(y19, y29), C31);
+ z19 = L_add(y09, s1);
+ s1 = L_sub(y09, L_shr_pos(s1, 1));
+
+ /* combination */
+ z08 = L_sub(r1, s2);
+ z28 = L_add(r1, s2);
+ z09 = L_add(s1, r2);
+ z29 = L_sub(s1, r2);
+
+ /* 2. FFT15 stage */
+ x00 = L_shr_pos(re[s * 15], SCALEFACTOR30_1);
+ x01 = L_shr_pos(im[s * 15], SCALEFACTOR30_1);
+ x02 = L_shr_pos(re[s * 3], SCALEFACTOR30_1);
+ x03 = L_shr_pos(im[s * 3], SCALEFACTOR30_1);
+ x04 = L_shr_pos(re[s * 21], SCALEFACTOR30_1);
+ x05 = L_shr_pos(im[s * 21], SCALEFACTOR30_1);
+ x06 = L_shr_pos(re[s * 9], SCALEFACTOR30_1);
+ x07 = L_shr_pos(im[s * 9], SCALEFACTOR30_1);
+ x08 = L_shr_pos(re[s * 27], SCALEFACTOR30_1);
+ x09 = L_shr_pos(im[s * 27], SCALEFACTOR30_1);
+
+ x10 = L_shr_pos(re[s * 5], SCALEFACTOR30_1);
+ x11 = L_shr_pos(im[s * 5], SCALEFACTOR30_1);
+ x12 = L_shr_pos(re[s * 23], SCALEFACTOR30_1);
+ x13 = L_shr_pos(im[s * 23], SCALEFACTOR30_1);
+ x14 = L_shr_pos(re[s * 11], SCALEFACTOR30_1);
+ x15 = L_shr_pos(im[s * 11], SCALEFACTOR30_1);
+ x16 = L_shr_pos(re[s * 29], SCALEFACTOR30_1);
+ x17 = L_shr_pos(im[s * 29], SCALEFACTOR30_1);
+ x18 = L_shr_pos(re[s * 17], SCALEFACTOR30_1);
+ x19 = L_shr_pos(im[s * 17], SCALEFACTOR30_1);
+
+ x20 = L_shr_pos(re[s * 25], SCALEFACTOR30_1);
+ x21 = L_shr_pos(im[s * 25], SCALEFACTOR30_1);
+ x22 = L_shr_pos(re[s * 13], SCALEFACTOR30_1);
+ x23 = L_shr_pos(im[s * 13], SCALEFACTOR30_1);
+ x24 = L_shr_pos(re[s * 1], SCALEFACTOR30_1);
+ x25 = L_shr_pos(im[s * 1], SCALEFACTOR30_1);
+ x26 = L_shr_pos(re[s * 19], SCALEFACTOR30_1);
+ x27 = L_shr_pos(im[s * 19], SCALEFACTOR30_1);
+ x28 = L_shr_pos(re[s * 7], SCALEFACTOR30_1);
+ x29 = L_shr_pos(im[s * 7], SCALEFACTOR30_1);
+
+ /* 1. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x02, x08);
+ r4 = L_sub(x02, x08);
+ r3 = L_add(x04, x06);
+ r2 = L_sub(x04, x06);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y00 = L_add(x00, r1);
+ r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x03, x09);
+ s4 = L_sub(x03, x09);
+ s3 = L_add(x05, x07);
+ s2 = L_sub(x05, x07);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y01 = L_add(x01, s1);
+ s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y02 = L_add(r1, s2);
+ y08 = L_sub(r1, s2);
+ y04 = L_sub(r3, s4);
+ y06 = L_add(r3, s4);
+
+ y03 = L_sub(s1, r2);
+ y09 = L_add(s1, r2);
+ y05 = L_add(s3, r4);
+ y07 = L_sub(s3, r4);
+
+ /* 2. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x12, x18);
+ r4 = L_sub(x12, x18);
+ r3 = L_add(x14, x16);
+ r2 = L_sub(x14, x16);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y10 = L_add(x10, r1);
+ r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x13, x19);
+ s4 = L_sub(x13, x19);
+ s3 = L_add(x15, x17);
+ s2 = L_sub(x15, x17);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y11 = L_add(x11, s1);
+ s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y12 = L_add(r1, s2);
+ y18 = L_sub(r1, s2);
+ y14 = L_sub(r3, s4);
+ y16 = L_add(r3, s4);
+
+ y13 = L_sub(s1, r2);
+ y19 = L_add(s1, r2);
+ y15 = L_add(s3, r4);
+ y17 = L_sub(s3, r4);
+
+ /* 3. FFT5 stage */
+
+ /* real part */
+ r1 = L_add(x22, x28);
+ r4 = L_sub(x22, x28);
+ r3 = L_add(x24, x26);
+ r2 = L_sub(x24, x26);
+ t = Mpy_32_xx(L_sub(r1, r3), C54);
+ r1 = L_add(r1, r3);
+ y20 = L_add(x20, r1);
+ r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1)));
+ r3 = L_sub(r1, t);
+ r1 = L_add(r1, t);
+ t = Mpy_32_xx((L_add(r4, r2)), C51);
+ r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1));
+ r2 = L_add(t, Mpy_32_xx(r2, C53));
+
+ /* imaginary part */
+ s1 = L_add(x23, x29);
+ s4 = L_sub(x23, x29);
+ s3 = L_add(x25, x27);
+ s2 = L_sub(x25, x27);
+ t = Mpy_32_xx(L_sub(s1, s3), C54);
+ s1 = L_add(s1, s3);
+ y21 = L_add(x21, s1);
+ s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1));
+ s3 = L_sub(s1, t);
+ s1 = L_add(s1, t);
+ t = Mpy_32_xx(L_add(s4, s2), C51);
+ s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1));
+ s2 = L_add(t, Mpy_32_xx(s2, C53));
+
+ /* combination */
+ y22 = L_add(r1, s2);
+ y28 = L_sub(r1, s2);
+ y24 = L_sub(r3, s4);
+ y26 = L_add(r3, s4);
+
+ y23 = L_sub(s1, r2);
+ y29 = L_add(s1, r2);
+ y25 = L_add(s3, r4);
+ y27 = L_sub(s3, r4);
+
+ /* 1. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y10, y20);
+ r2 = Mpy_32_xx(L_sub(y10, y20), C31);
+ z30 = L_add(y00, r1);
+ r1 = L_sub(y00, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y11, y21);
+ s2 = Mpy_32_xx(L_sub(y11, y21), C31);
+ z31 = L_add(y01, s1);
+ s1 = L_sub(y01, L_shr_pos(s1, 1));
+
+ /* combination */
+ z50 = L_sub(r1, s2);
+ z40 = L_add(r1, s2);
+ z51 = L_add(s1, r2);
+ z41 = L_sub(s1, r2);
+
+ /* 2. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y12, y22);
+ r2 = Mpy_32_xx(L_sub(y12, y22), C31);
+ z42 = L_add(y02, r1);
+ r1 = L_sub(y02, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y13, y23);
+ s2 = Mpy_32_xx(L_sub(y13, y23), C31);
+ z43 = L_add(y03, s1);
+ s1 = L_sub(y03, L_shr_pos(s1, 1));
+
+ /* combination */
+ z32 = L_sub(r1, s2);
+ z52 = L_add(r1, s2);
+ z33 = L_add(s1, r2);
+ z53 = L_sub(s1, r2);
+
+ /* 3. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y14, y24);
+ r2 = Mpy_32_xx(L_sub(y14, y24), C31);
+ z54 = L_add(y04, r1);
+ r1 = L_sub(y04, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y15, y25);
+ s2 = Mpy_32_xx(L_sub(y15, y25), C31);
+ z55 = L_add(y05, s1);
+ s1 = L_sub(y05, L_shr_pos(s1, 1));
+
+ /* combination */
+ z44 = L_sub(r1, s2);
+ z34 = L_add(r1, s2);
+ z45 = L_add(s1, r2);
+ z35 = L_sub(s1, r2);
+
+ /* 4. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y16, y26);
+ r2 = Mpy_32_xx(L_sub(y16, y26), C31);
+ z36 = L_add(y06, r1);
+ r1 = L_sub(y06, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y17, y27);
+ s2 = Mpy_32_xx(L_sub(y17, y27), C31);
+ z37 = L_add(y07, s1);
+ s1 = L_sub(y07, L_shr_pos(s1, 1));
+
+ /* combination */
+ z56 = L_sub(r1, s2);
+ z46 = L_add(r1, s2);
+ z57 = L_add(s1, r2);
+ z47 = L_sub(s1, r2);
+
+ /* 5. FFT3 stage */
+
+ /* real part */
+ r1 = L_add(y18, y28);
+ r2 = Mpy_32_xx(L_sub(y18, y28), C31);
+ z48 = L_add(y08, r1);
+ r1 = L_sub(y08, L_shr_pos(r1, 1));
+
+ /* imaginary part */
+ s1 = L_add(y19, y29);
+ s2 = Mpy_32_xx(L_sub(y19, y29), C31);
+ z49 = L_add(y09, s1);
+ s1 = L_sub(y09, L_shr_pos(s1, 1));
+
+ /* combination */
+ z38 = L_sub(r1, s2);
+ z58 = L_add(r1, s2);
+ z39 = L_add(s1, r2);
+ z59 = L_sub(s1, r2);
+
+ /* 1. FFT2 stage */
+ r1 = L_shr_pos(z00, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z30, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z01, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z31, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 2. FFT2 stage */
+ r1 = L_shr_pos(z16, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z46, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z17, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z47, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 3. FFT2 stage */
+ r1 = L_shr_pos(z02, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z32, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z03, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z33, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 4. FFT2 stage */
+ r1 = L_shr_pos(z18, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z48, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z19, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z49, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 5. FFT2 stage */
+ r1 = L_shr_pos(z04, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z34, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z05, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z35, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 6. FFT2 stage */
+ r1 = L_shr_pos(z20, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z50, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z21, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z51, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 7. FFT2 stage */
+ r1 = L_shr_pos(z06, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z36, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z07, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z37, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 8. FFT2 stage */
+ r1 = L_shr_pos(z22, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z52, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z23, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z53, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 9. FFT2 stage */
+ r1 = L_shr_pos(z08, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z38, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z09, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z39, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 10. FFT2 stage */
+ r1 = L_shr_pos(z24, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z54, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z25, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z55, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 11. FFT2 stage */
+ r1 = L_shr_pos(z10, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z40, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z11, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z41, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 12. FFT2 stage */
+ r1 = L_shr_pos(z26, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z56, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z27, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z57, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 13. FFT2 stage */
+ r1 = L_shr_pos(z12, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z42, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z13, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z43, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 14. FFT2 stage */
+ r1 = L_shr_pos(z28, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z58, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z29, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z59, SCALEFACTOR30_2);
+ *reh = L_add(r1, r2);
+ move32();
+ *rel = L_sub(r1, r2);
+ move32();
+ *imh = L_add(r3, r4);
+ move32();
+ *iml = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ /* 15. FFT2 stage */
+ r1 = L_shr_pos(z14, SCALEFACTOR30_2);
+ r2 = L_shr_pos(z44, SCALEFACTOR30_2);
+ r3 = L_shr_pos(z15, SCALEFACTOR30_2);
+ r4 = L_shr_pos(z45, SCALEFACTOR30_2);
+ *rel = L_add(r1, r2);
+ move32();
+ *reh = L_sub(r1, r2);
+ move32();
+ *iml = L_add(r3, r4);
+ move32();
+ *imh = L_sub(r3, r4);
+ move32();
+ rel += s, reh += s, iml += s;
+ imh += s;
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 32-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR32 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 752 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+
+
+static void fft32(Word32 *re, Word32 *im, Word16 s)
+{
+ Dyn_Mem_Deluxe_In(Word32 as, bs; Word32 x00, x01, x02, x03, x04, x05, x06, x07;
+ Word32 x08, x09, x10, x11, x12, x13, x14, x15; Word32 t00, t01, t02, t03, t04, t05, t06, t07;
+ Word32 t08, t09, t10, t11, t12, t13, t14, t15; Word32 s00, s01, s02, s03, s04, s05, s06, s07;
+ Word32 s08, s09, s10, s11, s12, s13, s14, s15;
+
+ Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15;
+ Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31;
+ Word32 y32, y33, y34, y35, y36, y37, y38, y39; Word32 y40, y41, y42, y43, y44, y45, y46, y47;
+ Word32 y48, y49, y50, y51, y52, y53, y54, y55; Word32 y56, y57, y58, y59, y60, y61, y62, y63;);
+
+ /* 1. FFT8 stage */
+ x00 = L_shr_pos(re[s * 0], SCALEFACTOR32_1);
+ x01 = L_shr_pos(im[s * 0], SCALEFACTOR32_1);
+ x02 = L_shr_pos(re[s * 4], SCALEFACTOR32_1);
+ x03 = L_shr_pos(im[s * 4], SCALEFACTOR32_1);
+ x04 = L_shr_pos(re[s * 8], SCALEFACTOR32_1);
+ x05 = L_shr_pos(im[s * 8], SCALEFACTOR32_1);
+ x06 = L_shr_pos(re[s * 12], SCALEFACTOR32_1);
+ x07 = L_shr_pos(im[s * 12], SCALEFACTOR32_1);
+ x08 = L_shr_pos(re[s * 16], SCALEFACTOR32_1);
+ x09 = L_shr_pos(im[s * 16], SCALEFACTOR32_1);
+ x10 = L_shr_pos(re[s * 20], SCALEFACTOR32_1);
+ x11 = L_shr_pos(im[s * 20], SCALEFACTOR32_1);
+ x12 = L_shr_pos(re[s * 24], SCALEFACTOR32_1);
+ x13 = L_shr_pos(im[s * 24], SCALEFACTOR32_1);
+ x14 = L_shr_pos(re[s * 28], SCALEFACTOR32_1);
+ x15 = L_shr_pos(im[s * 28], SCALEFACTOR32_1);
+
+ t00 = L_add(x00, x08);
+ t02 = L_sub(x00, x08);
+ t01 = L_add(x01, x09);
+ t03 = L_sub(x01, x09);
+ t04 = L_add(x02, x10);
+ t06 = L_sub(x02, x10);
+ t05 = L_add(x03, x11);
+ t07 = L_sub(x03, x11);
+ t08 = L_add(x04, x12);
+ t10 = L_sub(x04, x12);
+ t09 = L_add(x05, x13);
+ t11 = L_sub(x05, x13);
+ t12 = L_add(x06, x14);
+ t14 = L_sub(x06, x14);
+ t13 = L_add(x07, x15);
+ t15 = L_sub(x07, x15);
+
+ /* Pre-additions and core multiplications */
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+ t01 = L_add(t06, t14);
+ t02 = L_sub(t06, t14);
+ t00 = L_add(t07, t15);
+ t03 = L_sub(t07, t15);
+
+ Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03);
+
+ /* Post-additions */
+ y00 = L_add(s00, s02);
+ y08 = L_sub(s00, s02);
+ y01 = L_add(s01, s03);
+ y09 = L_sub(s01, s03);
+ y04 = L_sub(s04, s06);
+ y12 = L_add(s04, s06);
+ y05 = L_sub(s05, s07);
+ y13 = L_add(s05, s07);
+ y06 = L_add(s08, s14);
+ y14 = L_sub(s08, s14);
+ y07 = L_add(s09, s15);
+ y15 = L_sub(s09, s15);
+ y02 = L_add(s10, s12);
+ y10 = L_sub(s10, s12);
+ y03 = L_add(s11, s13);
+ y11 = L_sub(s11, s13);
+
+ /* 2. FFT8 stage */
+ x00 = L_shr_pos(re[s * 1], SCALEFACTOR32_1);
+ x01 = L_shr_pos(im[s * 1], SCALEFACTOR32_1);
+ x02 = L_shr_pos(re[s * 5], SCALEFACTOR32_1);
+ x03 = L_shr_pos(im[s * 5], SCALEFACTOR32_1);
+ x04 = L_shr_pos(re[s * 9], SCALEFACTOR32_1);
+ x05 = L_shr_pos(im[s * 9], SCALEFACTOR32_1);
+ x06 = L_shr_pos(re[s * 13], SCALEFACTOR32_1);
+ x07 = L_shr_pos(im[s * 13], SCALEFACTOR32_1);
+ x08 = L_shr_pos(re[s * 17], SCALEFACTOR32_1);
+ x09 = L_shr_pos(im[s * 17], SCALEFACTOR32_1);
+ x10 = L_shr_pos(re[s * 21], SCALEFACTOR32_1);
+ x11 = L_shr_pos(im[s * 21], SCALEFACTOR32_1);
+ x12 = L_shr_pos(re[s * 25], SCALEFACTOR32_1);
+ x13 = L_shr_pos(im[s * 25], SCALEFACTOR32_1);
+ x14 = L_shr_pos(re[s * 29], SCALEFACTOR32_1);
+ x15 = L_shr_pos(im[s * 29], SCALEFACTOR32_1);
+
+ t00 = L_add(x00, x08);
+ t02 = L_sub(x00, x08);
+ t01 = L_add(x01, x09);
+ t03 = L_sub(x01, x09);
+ t04 = L_add(x02, x10);
+ t06 = L_sub(x02, x10);
+ t05 = L_add(x03, x11);
+ t07 = L_sub(x03, x11);
+ t08 = L_add(x04, x12);
+ t10 = L_sub(x04, x12);
+ t09 = L_add(x05, x13);
+ t11 = L_sub(x05, x13);
+ t12 = L_add(x06, x14);
+ t14 = L_sub(x06, x14);
+ t13 = L_add(x07, x15);
+ t15 = L_sub(x07, x15);
+
+ /* Pre-additions and core multiplications */
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+ t01 = L_add(t06, t14);
+ t02 = L_sub(t06, t14);
+ t00 = L_add(t07, t15);
+ t03 = L_sub(t07, t15);
+
+ Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03);
+
+ /* Post-additions */
+ y16 = L_add(s00, s02);
+ y24 = L_sub(s00, s02);
+ y17 = L_add(s01, s03);
+ y25 = L_sub(s01, s03);
+ y20 = L_sub(s04, s06);
+ y28 = L_add(s04, s06);
+ y21 = L_sub(s05, s07);
+ y29 = L_add(s05, s07);
+ y22 = L_add(s08, s14);
+ y30 = L_sub(s08, s14);
+ y23 = L_add(s09, s15);
+ y31 = L_sub(s09, s15);
+ y18 = L_add(s10, s12);
+ y26 = L_sub(s10, s12);
+ y19 = L_add(s11, s13);
+ y27 = L_sub(s11, s13);
+
+ /* 3. FFT8 stage */
+ x00 = L_shr_pos(re[s * 2], SCALEFACTOR32_1);
+ x01 = L_shr_pos(im[s * 2], SCALEFACTOR32_1);
+ x02 = L_shr_pos(re[s * 6], SCALEFACTOR32_1);
+ x03 = L_shr_pos(im[s * 6], SCALEFACTOR32_1);
+ x04 = L_shr_pos(re[s * 10], SCALEFACTOR32_1);
+ x05 = L_shr_pos(im[s * 10], SCALEFACTOR32_1);
+ x06 = L_shr_pos(re[s * 14], SCALEFACTOR32_1);
+ x07 = L_shr_pos(im[s * 14], SCALEFACTOR32_1);
+ x08 = L_shr_pos(re[s * 18], SCALEFACTOR32_1);
+ x09 = L_shr_pos(im[s * 18], SCALEFACTOR32_1);
+ x10 = L_shr_pos(re[s * 22], SCALEFACTOR32_1);
+ x11 = L_shr_pos(im[s * 22], SCALEFACTOR32_1);
+ x12 = L_shr_pos(re[s * 26], SCALEFACTOR32_1);
+ x13 = L_shr_pos(im[s * 26], SCALEFACTOR32_1);
+ x14 = L_shr_pos(re[s * 30], SCALEFACTOR32_1);
+ x15 = L_shr_pos(im[s * 30], SCALEFACTOR32_1);
+
+ t00 = L_add(x00, x08);
+ t02 = L_sub(x00, x08);
+ t01 = L_add(x01, x09);
+ t03 = L_sub(x01, x09);
+ t04 = L_add(x02, x10);
+ t06 = L_sub(x02, x10);
+ t05 = L_add(x03, x11);
+ t07 = L_sub(x03, x11);
+ t08 = L_add(x04, x12);
+ t10 = L_sub(x04, x12);
+ t09 = L_add(x05, x13);
+ t11 = L_sub(x05, x13);
+ t12 = L_add(x06, x14);
+ t14 = L_sub(x06, x14);
+ t13 = L_add(x07, x15);
+ t15 = L_sub(x07, x15);
+
+ /* Pre-additions and core multiplications */
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+ t01 = L_add(t06, t14);
+ t02 = L_sub(t06, t14);
+ t00 = L_add(t07, t15);
+ t03 = L_sub(t07, t15);
+
+ Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03);
+
+ /* Post-additions */
+ y32 = L_add(s00, s02);
+ y40 = L_sub(s00, s02);
+ y33 = L_add(s01, s03);
+ y41 = L_sub(s01, s03);
+ y36 = L_sub(s04, s06);
+ y44 = L_add(s04, s06);
+ y37 = L_sub(s05, s07);
+ y45 = L_add(s05, s07);
+ y38 = L_add(s08, s14);
+ y46 = L_sub(s08, s14);
+ y39 = L_add(s09, s15);
+ y47 = L_sub(s09, s15);
+ y34 = L_add(s10, s12);
+ y42 = L_sub(s10, s12);
+ y35 = L_add(s11, s13);
+ y43 = L_sub(s11, s13);
+
+ /* 4. FFT8 stage */
+ x00 = L_shr_pos(re[s * 3], SCALEFACTOR32_1);
+ x01 = L_shr_pos(im[s * 3], SCALEFACTOR32_1);
+ x02 = L_shr_pos(re[s * 7], SCALEFACTOR32_1);
+ x03 = L_shr_pos(im[s * 7], SCALEFACTOR32_1);
+ x04 = L_shr_pos(re[s * 11], SCALEFACTOR32_1);
+ x05 = L_shr_pos(im[s * 11], SCALEFACTOR32_1);
+ x06 = L_shr_pos(re[s * 15], SCALEFACTOR32_1);
+ x07 = L_shr_pos(im[s * 15], SCALEFACTOR32_1);
+ x08 = L_shr_pos(re[s * 19], SCALEFACTOR32_1);
+ x09 = L_shr_pos(im[s * 19], SCALEFACTOR32_1);
+ x10 = L_shr_pos(re[s * 23], SCALEFACTOR32_1);
+ x11 = L_shr_pos(im[s * 23], SCALEFACTOR32_1);
+ x12 = L_shr_pos(re[s * 27], SCALEFACTOR32_1);
+ x13 = L_shr_pos(im[s * 27], SCALEFACTOR32_1);
+ x14 = L_shr_pos(re[s * 31], SCALEFACTOR32_1);
+ x15 = L_shr_pos(im[s * 31], SCALEFACTOR32_1);
+
+ t00 = L_add(x00, x08);
+ t02 = L_sub(x00, x08);
+ t01 = L_add(x01, x09);
+ t03 = L_sub(x01, x09);
+ t04 = L_add(x02, x10);
+ t06 = L_sub(x02, x10);
+ t05 = L_add(x03, x11);
+ t07 = L_sub(x03, x11);
+ t08 = L_add(x04, x12);
+ t10 = L_sub(x04, x12);
+ t09 = L_add(x05, x13);
+ t11 = L_sub(x05, x13);
+ t12 = L_add(x06, x14);
+ t14 = L_sub(x06, x14);
+ t13 = L_add(x07, x15);
+ t15 = L_sub(x07, x15);
+
+ /* Pre-additions and core multiplications */
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+ t01 = L_add(t06, t14);
+ t02 = L_sub(t06, t14);
+ t00 = L_add(t07, t15);
+ t03 = L_sub(t07, t15);
+
+ Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03);
+
+ /* Post-additions */
+ y48 = L_add(s00, s02);
+ y56 = L_sub(s00, s02);
+ y49 = L_add(s01, s03);
+ y57 = L_sub(s01, s03);
+ y52 = L_sub(s04, s06);
+ y60 = L_add(s04, s06);
+ y53 = L_sub(s05, s07);
+ y61 = L_add(s05, s07);
+ y54 = L_add(s08, s14);
+ y62 = L_sub(s08, s14);
+ y55 = L_add(s09, s15);
+ y63 = L_sub(s09, s15);
+ y50 = L_add(s10, s12);
+ y58 = L_sub(s10, s12);
+ y51 = L_add(s11, s13);
+ y59 = L_sub(s11, s13);
+
+ /* apply twiddle factors */
+ y00 = L_shr_pos(y00, SCALEFACTOR32_2);
+ y01 = L_shr_pos(y01, SCALEFACTOR32_2);
+ y02 = L_shr_pos(y02, SCALEFACTOR32_2);
+ y03 = L_shr_pos(y03, SCALEFACTOR32_2);
+ y04 = L_shr_pos(y04, SCALEFACTOR32_2);
+ y05 = L_shr_pos(y05, SCALEFACTOR32_2);
+ y06 = L_shr_pos(y06, SCALEFACTOR32_2);
+ y07 = L_shr_pos(y07, SCALEFACTOR32_2);
+ y08 = L_shr_pos(y08, SCALEFACTOR32_2);
+ y09 = L_shr_pos(y09, SCALEFACTOR32_2);
+ y10 = L_shr_pos(y10, SCALEFACTOR32_2);
+ y11 = L_shr_pos(y11, SCALEFACTOR32_2);
+ y12 = L_shr_pos(y12, SCALEFACTOR32_2);
+ y13 = L_shr_pos(y13, SCALEFACTOR32_2);
+ y14 = L_shr_pos(y14, SCALEFACTOR32_2);
+ y15 = L_shr_pos(y15, SCALEFACTOR32_2);
+ y16 = L_shr_pos(y16, SCALEFACTOR32_2);
+ y17 = L_shr_pos(y17, SCALEFACTOR32_2);
+ y32 = L_shr_pos(y32, SCALEFACTOR32_2);
+ y33 = L_shr_pos(y33, SCALEFACTOR32_2);
+ y48 = L_shr_pos(y48, SCALEFACTOR32_2);
+ y49 = L_shr_pos(y49, SCALEFACTOR32_2);
+ y40 = L_shr_pos(y40, SCALEFACTOR32_2);
+ y41 = L_shr_pos(y41, SCALEFACTOR32_2);
+
+ cplxMpy3_0(y18, y19, RotVector_32_32[2 * 0 + 0], RotVector_32_32[2 * 0 + 1]);
+ cplxMpy3_0(y20, y21, RotVector_32_32[2 * 1 + 0], RotVector_32_32[2 * 1 + 1]);
+ cplxMpy3_0(y22, y23, RotVector_32_32[2 * 2 + 0], RotVector_32_32[2 * 2 + 1]);
+ cplxMpy3_0(y24, y25, RotVector_32_32[2 * 3 + 0], RotVector_32_32[2 * 3 + 1]);
+ cplxMpy3_0(y26, y27, RotVector_32_32[2 * 4 + 0], RotVector_32_32[2 * 4 + 1]);
+ cplxMpy3_0(y28, y29, RotVector_32_32[2 * 5 + 0], RotVector_32_32[2 * 5 + 1]);
+ cplxMpy3_0(y30, y31, RotVector_32_32[2 * 6 + 0], RotVector_32_32[2 * 6 + 1]);
+ cplxMpy3_0(y34, y35, RotVector_32_32[2 * 7 + 0], RotVector_32_32[2 * 7 + 1]);
+ cplxMpy3_0(y36, y37, RotVector_32_32[2 * 8 + 0], RotVector_32_32[2 * 8 + 1]);
+ cplxMpy3_0(y38, y39, RotVector_32_32[2 * 9 + 0], RotVector_32_32[2 * 9 + 1]);
+ cplxMpy3_0(y42, y43, RotVector_32_32[2 * 10 + 0], RotVector_32_32[2 * 10 + 1]);
+ cplxMpy3_0(y44, y45, RotVector_32_32[2 * 11 + 0], RotVector_32_32[2 * 11 + 1]);
+ cplxMpy3_0(y46, y47, RotVector_32_32[2 * 12 + 0], RotVector_32_32[2 * 12 + 1]);
+ cplxMpy3_0(y50, y51, RotVector_32_32[2 * 13 + 0], RotVector_32_32[2 * 13 + 1]);
+ cplxMpy3_0(y52, y53, RotVector_32_32[2 * 14 + 0], RotVector_32_32[2 * 14 + 1]);
+ cplxMpy3_0(y54, y55, RotVector_32_32[2 * 15 + 0], RotVector_32_32[2 * 15 + 1]);
+ cplxMpy3_0(y56, y57, RotVector_32_32[2 * 16 + 0], RotVector_32_32[2 * 16 + 1]);
+ cplxMpy3_0(y58, y59, RotVector_32_32[2 * 17 + 0], RotVector_32_32[2 * 17 + 1]);
+ cplxMpy3_0(y60, y61, RotVector_32_32[2 * 18 + 0], RotVector_32_32[2 * 18 + 1]);
+ cplxMpy3_0(y62, y63, RotVector_32_32[2 * 19 + 0], RotVector_32_32[2 * 19 + 1]);
+
+ /* 1. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y00, y32);
+ t02 = L_sub(y00, y32);
+ t01 = L_add(y01, y33);
+ t03 = L_sub(y01, y33);
+ t04 = L_add(y16, y48);
+ t07 = L_sub(y16, y48);
+ t05 = L_add(y49, y17);
+ t06 = L_sub(y49, y17);
+
+ /* Post-additions */
+ re[s * 0] = L_add(t00, t04);
+ move32();
+ im[s * 0] = L_add(t01, t05);
+ move32();
+ re[s * 8] = L_sub(t02, t06);
+ move32();
+ im[s * 8] = L_sub(t03, t07);
+ move32();
+ re[s * 16] = L_sub(t00, t04);
+ move32();
+ im[s * 16] = L_sub(t01, t05);
+ move32();
+ re[s * 24] = L_add(t02, t06);
+ move32();
+ im[s * 24] = L_add(t03, t07);
+ move32();
+
+ /* 2. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y02, y34);
+ t02 = L_sub(y02, y34);
+ t01 = L_add(y03, y35);
+ t03 = L_sub(y03, y35);
+ t04 = L_add(y18, y50);
+ t07 = L_sub(y18, y50);
+ t05 = L_add(y51, y19);
+ t06 = L_sub(y51, y19);
+
+ /* Post-additions */
+ re[s * 1] = L_add(t00, t04);
+ move32();
+ im[s * 1] = L_add(t01, t05);
+ move32();
+ re[s * 9] = L_sub(t02, t06);
+ move32();
+ im[s * 9] = L_sub(t03, t07);
+ move32();
+ re[s * 17] = L_sub(t00, t04);
+ move32();
+ im[s * 17] = L_sub(t01, t05);
+ move32();
+ re[s * 25] = L_add(t02, t06);
+ move32();
+ im[s * 25] = L_add(t03, t07);
+ move32();
+
+ /* 3. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y04, y36);
+ t02 = L_sub(y04, y36);
+ t01 = L_add(y05, y37);
+ t03 = L_sub(y05, y37);
+ t04 = L_add(y20, y52);
+ t07 = L_sub(y20, y52);
+ t05 = L_add(y53, y21);
+ t06 = L_sub(y53, y21);
+
+ /* Post-additions */
+ re[s * 2] = L_add(t00, t04);
+ move32();
+ im[s * 2] = L_add(t01, t05);
+ move32();
+ re[s * 10] = L_sub(t02, t06);
+ move32();
+ im[s * 10] = L_sub(t03, t07);
+ move32();
+ re[s * 18] = L_sub(t00, t04);
+ move32();
+ im[s * 18] = L_sub(t01, t05);
+ move32();
+ re[s * 26] = L_add(t02, t06);
+ move32();
+ im[s * 26] = L_add(t03, t07);
+ move32();
+
+ /* 4. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y06, y38);
+ t02 = L_sub(y06, y38);
+ t01 = L_add(y07, y39);
+ t03 = L_sub(y07, y39);
+ t04 = L_add(y22, y54);
+ t07 = L_sub(y22, y54);
+ t05 = L_add(y55, y23);
+ t06 = L_sub(y55, y23);
+
+ /* Post-additions */
+ re[s * 3] = L_add(t00, t04);
+ move32();
+ im[s * 3] = L_add(t01, t05);
+ move32();
+ re[s * 11] = L_sub(t02, t06);
+ move32();
+ im[s * 11] = L_sub(t03, t07);
+ move32();
+ re[s * 19] = L_sub(t00, t04);
+ move32();
+ im[s * 19] = L_sub(t01, t05);
+ move32();
+ re[s * 27] = L_add(t02, t06);
+ move32();
+ im[s * 27] = L_add(t03, t07);
+ move32();
+
+ /* 5. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y08, y41);
+ t02 = L_sub(y08, y41);
+ t01 = L_sub(y09, y40);
+ t03 = L_add(y09, y40);
+ t04 = L_add(y24, y56);
+ t07 = L_sub(y24, y56);
+ t05 = L_add(y57, y25);
+ t06 = L_sub(y57, y25);
+
+ /* Post-additions */
+ re[s * 4] = L_add(t00, t04);
+ move32();
+ im[s * 4] = L_add(t01, t05);
+ move32();
+ re[s * 12] = L_sub(t02, t06);
+ move32();
+ im[s * 12] = L_sub(t03, t07);
+ move32();
+ re[s * 20] = L_sub(t00, t04);
+ move32();
+ im[s * 20] = L_sub(t01, t05);
+ move32();
+ re[s * 28] = L_add(t02, t06);
+ move32();
+ im[s * 28] = L_add(t03, t07);
+ move32();
+
+ /* 6. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y10, y42);
+ t02 = L_sub(y10, y42);
+ t01 = L_add(y11, y43);
+ t03 = L_sub(y11, y43);
+ t04 = L_add(y26, y58);
+ t07 = L_sub(y26, y58);
+ t05 = L_add(y59, y27);
+ t06 = L_sub(y59, y27);
+
+ /* Post-additions */
+ re[s * 5] = L_add(t00, t04);
+ move32();
+ im[s * 5] = L_add(t01, t05);
+ move32();
+ re[s * 13] = L_sub(t02, t06);
+ move32();
+ im[s * 13] = L_sub(t03, t07);
+ move32();
+ re[s * 21] = L_sub(t00, t04);
+ move32();
+ im[s * 21] = L_sub(t01, t05);
+ move32();
+ re[s * 29] = L_add(t02, t06);
+ move32();
+ im[s * 29] = L_add(t03, t07);
+ move32();
+
+ /* 7. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y12, y44);
+ t02 = L_sub(y12, y44);
+ t01 = L_add(y13, y45);
+ t03 = L_sub(y13, y45);
+ t04 = L_add(y28, y60);
+ t07 = L_sub(y28, y60);
+ t05 = L_add(y61, y29);
+ t06 = L_sub(y61, y29);
+
+ /* Post-additions */
+ re[s * 6] = L_add(t00, t04);
+ move32();
+ im[s * 6] = L_add(t01, t05);
+ move32();
+ re[s * 14] = L_sub(t02, t06);
+ move32();
+ im[s * 14] = L_sub(t03, t07);
+ move32();
+ re[s * 22] = L_sub(t00, t04);
+ move32();
+ im[s * 22] = L_sub(t01, t05);
+ move32();
+ re[s * 30] = L_add(t02, t06);
+ move32();
+ im[s * 30] = L_add(t03, t07);
+ move32();
+
+ /* 8. FFT4 stage */
+
+ /* Pre-additions */
+ t00 = L_add(y14, y46);
+ t02 = L_sub(y14, y46);
+ t01 = L_add(y15, y47);
+ t03 = L_sub(y15, y47);
+ t04 = L_add(y30, y62);
+ t07 = L_sub(y30, y62);
+ t05 = L_add(y63, y31);
+ t06 = L_sub(y63, y31);
+
+ /* Post-additions */
+ re[s * 7] = L_add(t00, t04);
+ move32();
+ im[s * 7] = L_add(t01, t05);
+ move32();
+ re[s * 15] = L_sub(t02, t06);
+ move32();
+ im[s * 15] = L_sub(t03, t07);
+ move32();
+ re[s * 23] = L_sub(t00, t04);
+ move32();
+ im[s * 23] = L_sub(t01, t05);
+ move32();
+ re[s * 31] = L_add(t02, t06);
+ move32();
+ im[s * 31] = L_add(t03, t07);
+ move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Function performs a complex 40-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR40 bits.
+ *
+ * \param [i/o] re real part
+ * \param [i/o] im imag part
+ * \param [i ] sx stride real and imag part
+ *
+ * \return void
+ */
+
+
+
+static void fft40(Word32 *re, Word32 *im, Word16 sx, Word32 *x)
+{
+ Dyn_Mem_Deluxe_In(const Word32 *W; Word16 dim1, dim2; Counter i, j;
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15;
+ Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;);
+
+ dim1 = 5;
+ move16();
+ dim2 = 8;
+ move16();
+
+ W = RotVector_40_32;
+
+ FOR (i = 0; i < dim2; i++)
+ {
+ FOR (j = 0; j < dim1; j++)
+ {
+ x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2];
+ move32();
+ x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2];
+ move32();
+ }
+ }
+
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft5(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+
+ FOR (i = 0; i < dim1; i++)
+ {
+ cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]);
+
+ IF (i == 0)
+ {
+ cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]);
+ cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]);
+ cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]);
+ cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]);
+ cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]);
+ cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]);
+ cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]);
+ }
+ ELSE
+ {
+ cplxMpy4_8_2(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], W[2 * (i - 1) + 0 * 2 * 4],
+ W[2 * (i - 1) + 0 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], W[2 * (i - 1) + 1 * 2 * 4],
+ W[2 * (i - 1) + 1 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], W[2 * (i - 1) + 2 * 2 * 4],
+ W[2 * (i - 1) + 2 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1], W[2 * (i - 1) + 3 * 2 * 4],
+ W[2 * (i - 1) + 3 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1], W[2 * (i - 1) + 4 * 2 * 4],
+ W[2 * (i - 1) + 4 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1], W[2 * (i - 1) + 5 * 2 * 4],
+ W[2 * (i - 1) + 5 * 2 * 4 + 1]);
+ cplxMpy4_8_2(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1], W[2 * (i - 1) + 6 * 2 * 4],
+ W[2 * (i - 1) + 6 * 2 * 4 + 1]);
+ }
+
+ t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1);
+ t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1);
+ t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1);
+ t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1);
+ t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1);
+ t06 = L_sub(x02, x10);
+ t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1);
+ t07 = L_sub(x03, x11);
+ t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1);
+ t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1);
+ t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1);
+ t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1);
+ t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1);
+ t14 = L_sub(x06, x14);
+ t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1);
+ t15 = L_sub(x07, x15);
+
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+
+ t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1);
+ t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1);
+ t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1);
+ t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1);
+
+ s12 = Mpy_32_32_lc3plus(L_add(t00, t02), C81_32);
+ s14 = Mpy_32_32_lc3plus(L_sub(t00, t02), C81_32);
+ s13 = Mpy_32_32_lc3plus(L_sub(t03, t01), C81_32);
+ s15 = Mpy_32_32_lc3plus(L_add(t01, t03), C82_32);
+
+ re[sx * i + sx * 0 * dim1] = L_add(s00, s02);
+ move32();
+ im[sx * i + sx * 0 * dim1] = L_add(s01, s03);
+ move32();
+ re[sx * i + sx * 1 * dim1] = L_add(s10, s12);
+ move32();
+ im[sx * i + sx * 1 * dim1] = L_add(s11, s13);
+ move32();
+ re[sx * i + sx * 2 * dim1] = L_sub(s04, s06);
+ move32();
+ im[sx * i + sx * 2 * dim1] = L_sub(s05, s07);
+ move32();
+ re[sx * i + sx * 3 * dim1] = L_add(s08, s14);
+ move32();
+ im[sx * i + sx * 3 * dim1] = L_add(s09, s15);
+ move32();
+ re[sx * i + sx * 4 * dim1] = L_sub(s00, s02);
+ move32();
+ im[sx * i + sx * 4 * dim1] = L_sub(s01, s03);
+ move32();
+ re[sx * i + sx * 5 * dim1] = L_sub(s10, s12);
+ move32();
+ im[sx * i + sx * 5 * dim1] = L_sub(s11, s13);
+ move32();
+ re[sx * i + sx * 6 * dim1] = L_add(s04, s06);
+ move32();
+ im[sx * i + sx * 6 * dim1] = L_add(s05, s07);
+ move32();
+ re[sx * i + sx * 7 * dim1] = L_sub(s08, s14);
+ move32();
+ im[sx * i + sx * 7 * dim1] = L_sub(s09, s15);
+ move32();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Combined FFT
+ *
+ * \param [i/o] re real part
+ * \param [i/o] im imag part
+ * \param [i ] W rotation factor
+ * \param [i ] dim1 length of fft1
+ * \param [i ] dim2 length of fft2
+ * \param [i ] sx stride real and imag part
+ * \param [i ] sc stride phase rotation coefficients
+ * \param [tmp] x 32-bit workbuffer of length=2*len
+ * \param [i ] Woff offset for addressing the rotation vector table
+ *
+ * \return void
+ */
+
+
+static void fftN2(Word32 *re, Word32 *im,
+#ifdef ENABLE_HR_MODE
+ const Word32 *W,
+#else
+ const Word16 *W,
+#endif
+ Word16 dim1, Word16 dim2, Word16 sx, Word16 sc,
+ Word16 Woff
+ , Word8 *scratchBuffer
+#ifdef ENABLE_FFT_RESCALE
+ , Word16 *scale
+#endif
+ )
+{
+ Dyn_Mem_Deluxe_In(Counter i, j;);
+
+ Word32 *x = scratchAlign(scratchBuffer, 0);
+
+ FOR (i = 0; i < dim2; i++)
+ {
+ FOR (j = 0; j < dim1; j++)
+ {
+ x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2];
+ move32();
+ x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2];
+ move32();
+ }
+ }
+
+ SWITCH (dim1)
+ {
+
+ case 4:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft4(&x[i * 2 * dim1]);
+ }
+ BREAK;
+ case 8:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft8(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+
+ case 10:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft10(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+ case 15:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft15(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+
+ BREAK;
+ case 16:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft16(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+ case 20:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft20(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+ case 30:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft30(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+ case 32:
+ FOR (i = 0; i < dim2; i++)
+ {
+ fft32(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2);
+ }
+ BREAK;
+#ifdef ENABLE_HR_MODE
+#if (defined LC3_FFT15)
+ case 60:
+ FOR (i = 0; i < dim2; i++)
+ {
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch);
+#else
+ fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch, NULL);
+#endif
+ }
+ BREAK;
+#endif
+#endif
+ default: ASSERT(0);
+ }
+
+#ifdef ENABLE_FFT_RESCALE
+ IF (scale)
+ {
+ *scale = s_max(sub(getScaleFactor32_lc3plus(x, dim1 * dim2 * 2), FFT_RESCALE_HR), 0); move16();
+
+#if defined(FUNCTION_scaleValues_32)
+ scaleValues_32(x, dim1 * dim2, *scale);
+#else
+ FOR (i = 0; i < dim1 * dim2 * 2; i++)
+ {
+ x[i] = L_shl_pos(x[i], *scale); move32();
+ }
+ }
+#endif
+#endif
+
+ SWITCH (dim2)
+ {
+ case 4:
+ {
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07;
+
+ j = add(8, 0);
+ FOR (i = 0; i < dim1; i++)
+ {
+ cplxMpy4_4_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]);
+ IF (i == 0)
+ {
+ cplxMpy4_4_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]);
+ cplxMpy4_4_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]);
+ cplxMpy4_4_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]);
+ }
+ ELSE
+ {
+ cplxMpy4_4_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1],
+ W[sc * i + j * 1 * dim1 - Woff], W[sc * i + j * 1 * dim1 + 1 - Woff]);
+ cplxMpy4_4_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1],
+ W[sc * i + j * 2 * dim1 - Woff], W[sc * i + j * 2 * dim1 + 1 - Woff]);
+ cplxMpy4_4_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1],
+ W[sc * i + j * 3 * dim1 - Woff], W[sc * i + j * 3 * dim1 + 1 - Woff]);
+ }
+
+ t00 = L_add(x00, x04);
+ t02 = L_sub(x00, x04);
+ t01 = L_add(x01, x05);
+ t03 = L_sub(x01, x05);
+ t04 = L_add(x02, x06);
+ t07 = L_sub(x02, x06);
+ t05 = L_add(x07, x03);
+ t06 = L_sub(x07, x03);
+
+ re[sx * i + sx * 0 * dim1] = L_add(t00, t04);
+ move32();
+ im[sx * i + sx * 0 * dim1] = L_add(t01, t05);
+ move32();
+ re[sx * i + sx * 1 * dim1] = L_sub(t02, t06);
+ move32();
+ im[sx * i + sx * 1 * dim1] = L_sub(t03, t07);
+ move32();
+ re[sx * i + sx * 2 * dim1] = L_sub(t00, t04);
+ move32();
+ im[sx * i + sx * 2 * dim1] = L_sub(t01, t05);
+ move32();
+ re[sx * i + sx * 3 * dim1] = L_add(t02, t06);
+ move32();
+ im[sx * i + sx * 3 * dim1] = L_add(t03, t07);
+ move32();
+ }
+
+ BREAK;
+ }
+
+#ifdef CR8_G_ADD_75MS
+ case 6:
+ {
+ Word32 y[2 * 10];
+ FOR (j = 0; j < dim2; j++)
+ {
+ cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]);
+ }
+ fft6(&y[0], &y[1], 2);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * 0 + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * 0 + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+
+ FOR (i = 1; i < dim1; i++)
+ {
+ cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1],
+ x[2 * i + 2 * (0 + 0) * dim1 + 1]);
+ cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1],
+ x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff],
+ W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]);
+ FOR (j = 2; j < dim2; j = j + 2)
+ {
+ cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1],
+ x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff],
+ W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]);
+ cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1],
+ x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff],
+ W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]);
+ }
+ fft6(&y[0], &y[1], 2);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * i + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * i + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+ }
+ BREAK;
+ }
+#endif
+
+ case 8:
+ {
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15;
+ Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;
+
+ FOR (i = 0; i < dim1; i++)
+ {
+ cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]);
+ IF (i == 0)
+ {
+ cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]);
+ cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]);
+ cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]);
+ cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]);
+ cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]);
+ cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]);
+ cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]);
+ }
+ ELSE
+ {
+ cplxMpy4_8_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1],
+ W[sc * i + sc * 1 * dim1 - Woff], W[sc * i + sc * 1 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1],
+ W[sc * i + sc * 2 * dim1 - Woff], W[sc * i + sc * 2 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1],
+ W[sc * i + sc * 3 * dim1 - Woff], W[sc * i + sc * 3 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1],
+ W[sc * i + sc * 4 * dim1 - Woff], W[sc * i + sc * 4 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1],
+ W[sc * i + sc * 5 * dim1 - Woff], W[sc * i + sc * 5 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1],
+ W[sc * i + sc * 6 * dim1 - Woff], W[sc * i + sc * 6 * dim1 + 1 - Woff]);
+ cplxMpy4_8_0(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1],
+ W[sc * i + sc * 7 * dim1 - Woff], W[sc * i + sc * 7 * dim1 + 1 - Woff]);
+ }
+
+ t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1);
+ t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1);
+ t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1);
+ t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1);
+ t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1);
+ t06 = L_sub(x02, x10);
+ t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1);
+ t07 = L_sub(x03, x11);
+ t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1);
+ t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1);
+ t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1);
+ t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1);
+ t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1);
+ t14 = L_sub(x06, x14);
+ t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1);
+ t15 = L_sub(x07, x15);
+
+ s00 = L_add(t00, t08);
+ s04 = L_sub(t00, t08);
+ s01 = L_add(t01, t09);
+ s05 = L_sub(t01, t09);
+ s08 = L_sub(t02, t11);
+ s10 = L_add(t02, t11);
+ s09 = L_add(t03, t10);
+ s11 = L_sub(t03, t10);
+ s02 = L_add(t04, t12);
+ s07 = L_sub(t04, t12);
+ s03 = L_add(t05, t13);
+ s06 = L_sub(t13, t05);
+
+ t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1);
+ t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1);
+ t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1);
+ t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1);
+
+ s12 = Mpy_32_xx(L_add(t00, t02), C81);
+ s14 = Mpy_32_xx(L_sub(t00, t02), C81);
+ s13 = Mpy_32_xx(L_sub(t03, t01), C81);
+ s15 = Mpy_32_xx(L_add(t01, t03), C82);
+
+ re[sx * i + sx * 0 * dim1] = L_add(s00, s02);
+ move32();
+ im[sx * i + sx * 0 * dim1] = L_add(s01, s03);
+ move32();
+ re[sx * i + sx * 1 * dim1] = L_add(s10, s12);
+ move32();
+ im[sx * i + sx * 1 * dim1] = L_add(s11, s13);
+ move32();
+ re[sx * i + sx * 2 * dim1] = L_sub(s04, s06);
+ move32();
+ im[sx * i + sx * 2 * dim1] = L_sub(s05, s07);
+ move32();
+ re[sx * i + sx * 3 * dim1] = L_add(s08, s14);
+ move32();
+ im[sx * i + sx * 3 * dim1] = L_add(s09, s15);
+ move32();
+ re[sx * i + sx * 4 * dim1] = L_sub(s00, s02);
+ move32();
+ im[sx * i + sx * 4 * dim1] = L_sub(s01, s03);
+ move32();
+ re[sx * i + sx * 5 * dim1] = L_sub(s10, s12);
+ move32();
+ im[sx * i + sx * 5 * dim1] = L_sub(s11, s13);
+ move32();
+ re[sx * i + sx * 6 * dim1] = L_add(s04, s06);
+ move32();
+ im[sx * i + sx * 6 * dim1] = L_add(s05, s07);
+ move32();
+ re[sx * i + sx * 7 * dim1] = L_sub(s08, s14);
+ move32();
+ im[sx * i + sx * 7 * dim1] = L_sub(s09, s15);
+ move32();
+ }
+ BREAK;
+ }
+
+ case 12:
+ {
+ Word32 y[2 * 20];
+ FOR (j = 0; j < dim2; j++)
+ {
+ cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]);
+ }
+ fft12(y);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * 0 + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * 0 + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+
+ FOR (i = 1; i < dim1; i++)
+ {
+ cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1],
+ x[2 * i + 2 * (0 + 0) * dim1 + 1]);
+ cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1],
+ x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff],
+ W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]);
+ FOR (j = 2; j < dim2; j = j + 2)
+ {
+ cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1],
+ x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff],
+ W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]);
+ cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1],
+ x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff],
+ W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]);
+ }
+ fft12(y);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * i + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * i + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+ }
+ BREAK;
+ }
+
+#if defined(ENABLE_HR_MODE)
+ case 16:
+ {
+ Word32 y[2 * 20];
+ FOR (j = 0; j < dim2; j++)
+ {
+ cplxMpy4_16_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]);
+ }
+
+ fft16(&y[0], &y[1], 2);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * 0 + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * 0 + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+
+ FOR (i = 1; i < dim1; i++)
+ {
+ cplxMpy4_16_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1],
+ x[2 * i + 2 * (0 + 0) * dim1 + 1]);
+ cplxMpy4_16_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1],
+ x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff],
+ W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]);
+ FOR (j = 2; j < dim2; j = j + 2)
+ {
+ cplxMpy4_16_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1],
+ x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff],
+ W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]);
+ cplxMpy4_16_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1],
+ x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff],
+ W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]);
+ }
+ fft16(&y[0], &y[1], 2);
+ FOR (j = 0; j < dim2; j++)
+ {
+ re[sx * i + sx * j * dim1] = y[2 * j];
+ move32();
+ im[sx * i + sx * j * dim1] = y[2 * j + 1];
+ move32();
+ }
+ }
+ BREAK;
+ }
+# endif
+ default: ASSERT(0);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/**
+ * \brief Complex valued FFT
+ *
+ * \param [i/o] re real part
+ * \param [i/o] im imag part
+ * \param [i ] sizeOfFft length of fft
+ * \param [i ] s stride real and imag part
+ * \param [i ] scale scalefactor
+ *
+ * \return void
+ */
+
+
+
+/* x is the scratch buffer */
+void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 length, Word16 s, Word16 *scale, Word32 *x)
+{
+#if (defined ENABLE_FFT_RESCALE) && ((defined LC3_FFT30) || (defined ENABLE_HR_MODE))
+ Word16 fftN2scale = 0;
+#endif
+
+#ifdef ENABLE_HR_MODE
+ Word8 scratch[6128] = {0};
+#else
+ Word8 scratch[4068] = {0};
+#endif
+
+ SWITCH (length)
+ {
+
+ case 10:
+ fft10(re, im, s);
+ *scale = add(*scale, SCALEFACTOR10);
+ move16();
+ BREAK;
+ case 16:
+ fft16(re, im, s);
+ *scale = add(*scale, SCALEFACTOR16);
+ move16();
+ BREAK;
+ case 20:
+ fft20(re, im, s);
+ *scale = add(*scale, SCALEFACTOR20);
+ move16();
+ BREAK;
+ case 30:
+ fft30(re, im, s);
+ *scale = add(*scale, SCALEFACTOR30);
+ move16();
+ BREAK;
+ case 32:
+ fft32(re, im, s);
+ *scale = add(*scale, SCALEFACTOR32);
+ move16();
+ BREAK;
+ case 40:
+ fft40(re, im, s, x);
+ *scale = add(*scale, SCALEFACTOR40);
+ move16();
+ BREAK;
+ case 48:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR48);
+ move16();
+ BREAK;
+ case 60:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch);
+#else
+ fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR60);
+ move16();
+ BREAK;
+ case 64:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR64);
+ move16();
+ BREAK;
+ case 80:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch);
+#else
+ fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR80);
+ move16();
+ BREAK;
+ case 90:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch);
+#else
+ fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR90);
+ move16();
+ BREAK;
+
+ case 120:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch);
+#else
+ fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR120);
+ move16();
+ BREAK;
+ case 128:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR128);
+ move16();
+ BREAK;
+ case 160:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch);
+#else
+ fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR160);
+ move16();
+ BREAK;
+ case 180:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch);
+ *scale = add(*scale, SCALEFACTOR180);
+#else
+ fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch, &fftN2scale);
+ *scale = add(*scale, SCALEFACTOR180);
+ *scale = sub(*scale, fftN2scale); move16();
+#endif
+
+ move16();
+ BREAK;
+ case 192:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR192);
+ move16();
+ BREAK;
+ case 240:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch);
+ *scale = add(*scale, SCALEFACTOR240);
+#else
+ fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch, &fftN2scale);
+ *scale = add(*scale, SCALEFACTOR240);
+ *scale = sub(*scale, fftN2scale); move16();
+#endif
+ move16();
+ BREAK;
+ case 256:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR256);
+ move16();
+ BREAK;
+ case 384:
+#ifndef ENABLE_FFT_RESCALE
+ fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch);
+#else
+ fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch, NULL);
+#endif
+ *scale = add(*scale, SCALEFACTOR384);
+ move16();
+ BREAK;
+#ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+ case 360:
+ fftN2(re, im, RotVector_720, 30, 12, s, 2, 60, scratch, &fftN2scale);
+ *scale = add(*scale, SCALEFACTOR360); move16();
+ *scale = sub(*scale, fftN2scale); move16();
+ BREAK;
+#endif
+ case 480:
+#ifndef ENABLE_FFT_RESCALE
+#ifndef ENABLE_FFT_30X16
+ fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch);
+#else
+ fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch);
+#endif
+ *scale = add(*scale, SCALEFACTOR480); move16();
+#else
+#ifndef ENABLE_FFT_30X16
+ fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch, &fftN2scale);
+#else
+ fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch, &fftN2scale);
+#endif
+ *scale = add(*scale, SCALEFACTOR480); move16();
+ *scale = sub(*scale, fftN2scale); move16();
+#endif
+ BREAK;
+#endif
+ default: ASSERT(0);
+ }
+}
+
+
+#define RFFT_TWIDDLE1(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \
+ do \
+ { \
+ xb0 = L_shr_pos(x[2 * i + 0], 2); \
+ xb1 = L_shr_pos(x[2 * i + 1], 2); \
+ xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \
+ xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \
+ t1 = L_sub(xb0, xt0); \
+ t2 = L_add(xb1, xt1); \
+ t3 = L_sub(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \
+ t4 = L_add(Mpy_32_32_lc3plus(t1, w2), Mpy_32_32_lc3plus(t2, w1)); \
+ t1 = L_add(xb0, xt0); \
+ t2 = L_sub(xb1, xt1); \
+ } while (0)
+
+#define RFFT_TWIDDLE2(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \
+ do \
+ { \
+ xb0 = L_shr_pos(x[2 * i + 0], 2); \
+ xb1 = L_shr_pos(x[2 * i + 1], 2); \
+ xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \
+ xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \
+ t1 = L_sub(xb0, xt0); \
+ t2 = L_add(xb1, xt1); \
+ t3 = L_add(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \
+ t4 = L_sub(Mpy_32_32_lc3plus(t2, w1), Mpy_32_32_lc3plus(t1, w2)); \
+ t1 = L_add(xb0, xt0); \
+ t2 = L_sub(xb1, xt1); \
+ } while (0)
+
+
+
+static const Word32 *rfft_twid(int size)
+{
+ SWITCH (size)
+ {
+ case 32: return RealFFT32_twid;
+ case 40: return RealFFT40_twid;
+ case 64: return RealFFT64_twid;
+ case 80: return RealFFT80_twid;
+ case 96: return RealFFT96_twid;
+ case 128: return RealFFT128_twid;
+ case 192: return RealFFT192_twid;
+ case 256: return RealFFT256_twid;
+ case 384: return RealFFT384_twid;
+ case 512: return RealFFT512_twid;
+ case 768: return RealFFT768_twid;
+ default: ASSERT(0);
+ }
+ return NULL;
+}
+
+
+void BASOP_rfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer)
+{
+ Dyn_Mem_Deluxe_In(Counter i; Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1;
+ Word32 * workBuffer; const Word32 *w32;);
+
+ workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * sizeOfFft */
+ w32 = rfft_twid(sizeOfFft);
+
+ sizeOfFft2 = shr_pos(sizeOfFft, 1);
+ sizeOfFft4 = shr_pos(sizeOfFft, 2);
+ sizeOfFft8 = shr_pos(sizeOfFft, 3);
+
+ BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer);
+
+ xb0 = L_shr_pos(x[0], 1);
+ xb1 = L_shr_pos(x[1], 1);
+ x[0] = L_add(xb0, xb1);
+ move32();
+ x[1] = L_sub(xb0, xb1);
+ move32();
+
+ FOR (i = 1; i < sizeOfFft8; i++)
+ {
+ RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1);
+ x[2 * i] = L_sub(t1, t3);
+ move32();
+ x[2 * i + 1] = L_sub(t2, t4);
+ move32();
+ x[sizeOfFft - 2 * i] = L_add(t1, t3);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4));
+ move32();
+ }
+
+ FOR (i = sizeOfFft8; i < sizeOfFft4; i++)
+ {
+ RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1,
+ xt0, xt1);
+ x[2 * i] = L_sub(t1, t3);
+ move32();
+ x[2 * i + 1] = L_sub(t2, t4);
+ move32();
+ x[sizeOfFft - 2 * i] = L_add(t1, t3);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4));
+ move32();
+ }
+
+ x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_negate(L_shr_pos(x[2 * i + 1], 1));
+ move32();
+
+ *scale = add(*scale, 1);
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+
+void BASOP_irfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer)
+{
+ Dyn_Mem_Deluxe_In(Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1;
+ Word32 * workBuffer; const Word32 *w32; Counter i;);
+
+ workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * BASOP_CFFT_MAX_LENGTH */
+
+ w32 = rfft_twid(sizeOfFft);
+
+ sizeOfFft2 = shr_pos(sizeOfFft, 1);
+ sizeOfFft4 = shr_pos(sizeOfFft, 2);
+ sizeOfFft8 = shr_pos(sizeOfFft, 3);
+
+ xb0 = L_shr_pos(x[0], 2);
+ xb1 = L_shr_pos(x[1], 2);
+ x[0] = L_add(xb0, xb1);
+ move32();
+ x[1] = L_sub(xb1, xb0);
+ move32();
+
+ FOR (i = 1; i < sizeOfFft8; i++)
+ {
+ RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1);
+ x[2 * i] = L_sub(t1, t3);
+ move32();
+ x[2 * i + 1] = L_sub(t4, t2);
+ move32();
+ x[sizeOfFft - 2 * i] = L_add(t1, t3);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_add(t2, t4);
+ move32();
+ }
+
+ FOR (i = sizeOfFft8; i < sizeOfFft4; i++)
+ {
+ RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1,
+ xt0, xt1);
+ x[2 * i] = L_sub(t1, t3);
+ move32();
+ x[2 * i + 1] = L_sub(t4, t2);
+ move32();
+ x[sizeOfFft - 2 * i] = L_add(t1, t3);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_add(t2, t4);
+ move32();
+ }
+
+ x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1);
+ move32();
+ x[sizeOfFft - 2 * i + 1] = L_shr_pos(x[2 * i + 1], 1);
+ move32();
+
+ BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer);
+
+ /* If you want BASOP_irfft to be inverse to BASOP_rfft then the result needs
+ * to be normalised by sizeOfFft */
+ FOR (i = 0; i < sizeOfFft2; i++)
+ {
+ x[2 * i + 1] = L_negate(x[2 * i + 1]);
+ move32();
+ }
+
+ *scale = add(*scale, 2);
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h
new file mode 100644
index 0000000000000000000000000000000000000000..90571c6cd22a4fc5cba4a44dbbbaacc2abafcc47
--- /dev/null
+++ b/lib_lc3plus/functions.h
@@ -0,0 +1,836 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+#include "defines.h"
+
+#include "stl.h"
+#ifdef DYNMEM_COUNT
+#include "dynmem.h"
+#endif
+
+#include "basop_util_lc3plus.h"
+#include "basop32.h"
+#include "constants.h"
+#include "lc3.h"
+#include "setup_dec_lc3.h" /* for decoder state handle ptr */
+#include "setup_enc_lc3.h" /* for encoder state handle ptr */
+#include "basop_mpy_lc3plus.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#define PRINTF printf /* C console debug, */
+#define ASSERT(test) assert(test)
+
+typedef struct
+{
+ Word16 lead_sign_ind; /* this MPVQ index is the first part of the total PVQ index */
+ UWord32 index, size; /* this MPVQ index is the second part of the total PVQ index */
+ Word16 dim, k_val;
+ Word16 vec[PVQ_MAX_VEC_SIZE]; /* integer vector */
+} PvqEntry_fx;
+
+typedef enum {
+ LC3_CON_TEC_NS_STD, /* 0 */
+ LC3_CON_TEC_PHASE_ECU, /* 2 */
+ LC3_CON_TEC_TDPLC, /* 3 */
+ LC3_CON_TEC_NS_ADV, /* 4 */
+ LC3_CON_TEC_FREQ_MUTING, /* 5 */
+} LC3_ConcealTechnique;
+
+void WarnMsg(char *msg);
+void ExitMsg(char *msg);
+void AssertMsg(int true_flag, char *msg);
+
+void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx,
+ Word16 frame_dms, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[],
+ Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms,
+ Word16 max_len, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+ , Word16 near_nyquist_flag
+);
+
+void TnsUpdate_fx(Word16 *tns_numfilters, Word16 *long_startfreq, const Word16 **subdiv_startfreq,
+ const Word16 **subdiv_stopfreq, Word16 frame_length, Word16 tab_idx);
+
+void processResidualDecoding_fx(Word32 spectrum[], Word16 spectrum_e, Word16 L_spec, UWord8 prm[], Word16 resQBits
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processPreemph_fx(Word16 *x, Word16 len, Word16 mem[], Word16 memLen, Word16 out[], Word16 *outLen, Word16 mu);
+
+void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx,
+ Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[],
+#ifdef ENABLE_HR_MODE
+ Word32 xq[],
+#else
+ Word16 xq[],
+#endif
+ Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processMdctShaping_fx(Word32 x[],
+#ifdef ENABLE_HR_MODE
+ Word32 scf[],
+#else
+ Word16 scf[],
+#endif
+ Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts);
+
+void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e);
+
+void processMdct_fx(
+#ifdef ENABLE_HR_MODE
+ Word32 x[],
+#else
+ Word16 x[],
+#endif
+ Word16 x_exp, Word16 N,
+#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+# ifdef ENABLE_HR_MODE
+ Word16 hrmode, /* i: indicate high precision */
+# endif
+#endif
+#ifdef ENABLE_HR_MODE
+ const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#else
+ const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#endif
+ Word16 wLen,
+#ifdef ENABLE_HR_MODE
+ Word32 mem[], /* i/o: last block of input samples */
+#else
+ Word16 mem[], /* i/o: last block of input samples */
+#endif
+ Word16 memLen,
+ Word32 y[], Word16 *y_e, Word8 *scratchBuffer);
+
+void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer);
+
+void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N);
+
+void ProcessingIMDCT(Word32 y[], Word16 *y_e,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+ Word32 mem[], /* i/o: overlap add memory */
+#else
+ const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+ Word16 mem[], /* i/o: overlap add memory */
+#endif
+ Word16 *mem_e,
+#ifdef ENABLE_HR_MODE
+ Word32 x[], /* o: time signal out */
+#else
+ Word16 x[], /* o: time signal out */
+#endif
+ Word16 wLen,
+ Word16 N, Word16 memLen, Word16 frame_dms,
+ Word16 concealMethod, Word16 bfi, Word16 prev_bfi, Word16 nbLostFramesInRow, AplcSetup *plcAd,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+#ifdef ENABLE_HR_MODE
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word16 hrmode, Word32 *workBuffer);
+# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer);
+# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+#else
+void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer);
+#endif
+
+#ifdef ENABLE_HR_MODE
+Word16 find_last_nz_pair(const Word32 x[], Word16 length);
+#else
+Word16 find_last_nz_pair(const Word16 x[], Word16 length);
+#endif
+
+PvqEntry_fx mpvq_index_fx(const Word16 *vec_in, Word16 dim_in, Word16 k_val_local);
+void mpvq_deindex_fx(const PvqEntry_fx *entry, UWord32 *h_mem, Word16 *vec_out);
+
+void pvq_enc_search_fx(const Word16 *x, /* i: target vector to quantize Qin */
+ Word16 * rt_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 */
+ Word16 * rt_near, /* o: outl_near o, raw pulses (non-scaled short) Q0 */
+ Word16 * rtA, /* o: A section raw pulses (non-scaled short) Q0 */
+ Word16 * rtB, /* o: B section raw pulses (non-scaled short) Q0 */
+ Word32 *L_corr, /* o: 4 un-normalized correlation sums for outl_far, near, outl, A, AB */
+ Word32 *L_search_en, /* o: 4 energy sums for out_far, outl_near, A, AB */
+ Word16 *pulses_fin, /* i: number of allocated pulses to outl A, AB section */
+ Word16 *pulses_proj, /* i: number of proj pulses pulses to outl, A , AB section */
+
+ const Word16 dim, /* i: Length of vector */
+ const Word16 dimA /* i: Length of vector A section */
+);
+
+PvqEntry_fx get_size_mpvq_calc_offset_fx(Word16 dim_in, Word16 k_val_in, UWord32 *h_mem);
+
+Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */
+ Word16 * y, /* o: decoded vector (non-scaled int) */
+ const Word16 k_val, /* i: number of allocated pulses */
+ const Word16 dim, /* i: Length of vector */
+ const Word16 LS_ind, /* i; lS index 1 bit */
+ const UWord32 UL_MPVQ_ind /* i; MPVQ index */
+);
+
+void pvq_dec_en1_norm_fx( /* */
+#ifdef ENABLE_HR_MODE
+ Word32 * xq, /* o: en1 normalized decoded vector (Q14) */
+#else
+ Word16 * xq, /* o: en1 normalized decoded vector (Q14) */
+#endif
+ const Word16 *y, /* i: decoded vector (non-scaled int) */
+ const Word16 kval_max, /* i: max possible K in Q0 kO or kA */
+ const Word16 dim, /* i: Length of vector */
+ const Word16 neg_glob_gain /* i: a Global Gain (negated to fit 1.0 in Q15 as -1.0) */
+);
+
+#ifdef ENABLE_HR_MODE
+#ifdef WIN32
+#define mexPrintf(x, y) printf(x, y)
+#endif
+#endif
+
+void pvq_dec_en1_normQ14_fx( /* Have to be used by both encoder and decoder */
+#ifdef ENABLE_HR_MODE
+ Word32 * xq, /* o: en1 normalized decoded vector (Q14) */
+#else
+ Word16 * xq, /* o: en1 normalized decoded vector (Q14) */
+#endif
+ const Word16 *y, /* i: decoded vector (non-scaled int) */
+ const Word16 k_val_max, /* i: max possible K in Q0 kO or kA */
+ const Word16 dim /* i: Length of vector */
+);
+
+
+#ifdef ENABLE_HR_MODE
+void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ);
+#else
+void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14);
+#endif
+
+Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side, Word16 mask_side, Word16 nbbits,
+#ifdef ENABLE_HR_MODE
+ Word32 xq[],
+#else
+ Word16 xq[],
+#endif
+ Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz,
+ Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode,
+ Word16 enable_lpc_weighting, Word8 *scratchBuffer);
+
+void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec,
+ Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode,
+ Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx,
+ Word16 frame_dms,
+ Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx,
+ Word16 *b_left,
+ Word16 *resBits,
+#ifdef ENABLE_HR_MODE
+ Word32 *x,
+#else
+ Word16 *x,
+#endif
+ Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processAriDecoderScaling_fx(
+#ifdef ENABLE_HR_MODE
+ Word32 *datain,
+#else
+ Word16 *data16,
+#endif
+ Word16 dataLen, Word32 *data32, Word16 *data_e);
+
+void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off);
+
+void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp,
+ const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index,
+ const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp
+#ifdef CR8_E_TONE_DETECTOR
+#ifdef ENABLE_HR_MODE
+ , Word16 frame_dms , Word16 hrmode);
+#else
+ );
+#endif
+#else
+ );
+#endif
+void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms);
+
+void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[],
+ Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx,
+ Word16 frame_dms, Word8 *scratchBuffer
+ , Word16 bps
+ );
+
+void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8,
+ Word16 len, Word16 *normcorr, Word16 *mem_pitch,
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ Word16 *pitch_flag,
+#endif
+ Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer);
+
+void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *old_wsp_exp, Word16 *old_wsp,
+ Word16 old_wsplen, Word16 *param, Word16 *wsp, Word16 len, Word16 *mem_normcorr,
+ Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch,
+ Word16 wsp_exp, Word16 frame_dms, Word8 *scratchBuffer
+#ifdef CR9_K_REDUCE_NORM_CORR_TH
+ ,Word16 hrmode
+#endif
+);
+
+void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len,
+ Word16 *old_e, Word16 *x, Word16 *old_x, Word16 *y, Word16 *old_y, Word16 ltpf,
+ Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr,
+ Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi,
+ Word16 concealMethod,
+ Word16 damping, Word16 *old_scale_fac_idx,
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms,
+#endif
+ Word8 *scratchBuffer);
+
+void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch);
+
+void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf,
+ Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping
+ );
+
+void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */
+ Word32 *L_prm_idx, /* o: indeces . negative == unused */
+#ifdef ENABLE_HR_MODE
+ Word32 *scf_q, /* o: quantized scf M */
+#else
+ Word16 *scf_q, /* o: quantized scf M */
+#endif
+ Word8 * scratchBuffer);
+
+Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */
+ Word32 *L_prm_idx, /* i: indeces */
+#ifdef ENABLE_HR_MODE
+ Word32 scf_q[],
+#else
+ Word16 scf_q[],
+#endif
+ Word8 *scratchBuffer); /* o: M */
+
+void processSnsInterpolateScf_fx(
+#ifdef ENABLE_HR_MODE
+ Word32 *scf_q, Word32 mdct_scf[],
+#else
+ Word16 *scf_q, Word16 mdct_scf[],
+#endif
+ Word16 mdct_scf_exp[], Word16 inv_scf,
+ Word16 n_bands, Word8 *scratchBuffer);
+
+void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len);
+void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr, Word32 len);
+
+void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi,
+ Word16 frame_length, Word16 la_zeroes,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[],
+#else
+ const Word16 w[],
+#endif
+ Word16 x_fx[], Word16 ola_mem[],
+ Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping,
+ Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed,
+ AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ , Word32 rel_pitch_change
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , Word16 *alpha_type_2_table
+#endif
+ );
+
+void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length,
+ Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi,
+ Word16 scf_q[], Word16 *ns_cum_alpha
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+ );
+
+void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen);
+
+
+void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen,
+ Word16 *PhECU_oold_grp_shape_fx, Word16 *PhECU_old_grp_shape_fx);
+
+Word32 winEnCalc(const Word16 *, const Word16, const Word16 *, const Word16, const Word16, Word16 *);
+
+void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx,
+ Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi,
+ Word16 scf_q[], Word16 *ns_cum_alpha, AplcSetup *plcAd);
+
+void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi,
+ Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen,
+ Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer
+# ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+# endif
+ );
+
+void processPLCapply_fx(
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 *concealMethod,
+#else
+ Word16 concealMethod,
+#endif
+ Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi,
+ Word16 frame_length, Word16 la_zeroes,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[],
+#else
+ const Word16 w[],
+#endif
+ Word16 x_fx[], Word16 ola_mem[],
+ Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int,
+ Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ , Word32 rel_pitch_change
+
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , Word16 *alpha_type_2_table
+#endif
+ );
+
+void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec);
+void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten,
+ Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1,
+ Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx,
+ Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms,
+ Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , UWord8 plc_fadeout_type
+#endif
+ );
+
+void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb,
+ Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow,
+ Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , UWord8 plc_fadeout_type
+#endif
+ );
+
+void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m);
+
+void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands,
+ Word16 lpc_order, Word8 *scratchBuffer);
+
+void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms,
+ Word8 *scratchBuffer);
+
+void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m);
+
+void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi,
+ Word16 prev_bfi, Word16 prev_prev_bfi, Word16 *stab_fac);
+
+void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi,
+ Word16 *xfp_fx, Word16 xfp_exp_fx,Word16 margin_xfp,
+ Word16 fs_idx,
+ Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx,
+ Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx,
+ Word16 *oold_Ltot_exp_fx, Word16 *old_Ltot_exp_fx);
+
+void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx,
+ const Word16 lpc_order, const Word16 *pcmbufHist_fx,
+ const Word16 frame_length, const Word16 frame_dms, const Word16 fs_idx,
+ const Word16 nbLostFramesInRow, const Word16 overlap,
+ const Word16 stabFac_fx, Word16 *fract, Word16 *seed_fx,
+ Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn,
+ Word16 *alpha, Word16 max_len_pcm_plc,
+ Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q,
+ Word8 *scratchBuffer
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+ ,UWord8 plc_fadeout_type
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ ,Word16 *alpha_type_2_table
+#endif
+);
+
+void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth, const Word16 synth_exp,
+#ifdef ENABLE_HR_MODE
+ const Word32 *win,
+#else
+ const Word16 *win,
+#endif
+ const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer);
+
+void plc_phEcu_F0_refine_first_fx(Word16 *plocs, const Word16 n_plocs_in, Word32 *L_f0est,
+ const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15,
+ const Word16 nSubm);
+void plc_phEcu_LF_peak_analysis_fx(Word16 *plocs, Word16 *n_plocs, Word32 *L_f0estQ16, const Word16 *mag,
+ const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15,
+ const Word16 nSubm, Word16 maxPlocs, Word8 *scratchBuffer);
+
+Word16 plc_phEcuSetF0Hz_fx(Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr);
+
+void create_sin2_taper_fx(Word16 *, Word16, Word16);
+
+void plc_phEcu_initWord16(Word16 * vec, /*i/o : vector pointer */
+ const Word16 value, /*i : short initialization value */
+ const Word16 len); /*i : number of elements */
+
+Word16 plc_phEcu_ratio_fx(const Word32, const Word32, Word16 *);
+
+void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */
+ const Word16 len, /* i : length */
+ Word16 * minvalPtr); /* o : min value Ptr */
+
+void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */
+ const Word16 len, /* i : length */
+ Word16 * maxvalPtr); /* o : *maxvalPtr */
+
+void Scale_sig_sat(Word16 x[], /* i/o: signal to scale, possibly saturated Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0); /* i : exponent: x = round(x << exp) Qx ?exp */
+
+void Processing_ITDA_WIN_OLA(Word32 L_x_tda[], Word16 *y_e,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[],
+#else
+ const Word16 w[],
+#endif
+ Word16 mem[], Word16 *mem_e, Word16 x[],
+ Word16 wLen, Word16 N, Word16 memLen);
+
+void trans_burst_ana_fx(const Word16 *xfp, /* i : Input signal Qspec */
+ Word16 * mag_chg, /* o : Magnitude modification Q15 */
+ Word16 *ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */
+ Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */
+ const Word16 output_frame, /* i : Frame length */
+ const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */
+ const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=stable (==st->env_stab ) */
+ Word16 * alpha, /* o : Magnitude modification factors for fade to average */
+ Word16 * beta, /* : Magnitude modification factors for fade to average */
+ Word16 * beta_mute, /* i/o : Factor for long-term mute */
+ Word16 * Xavg, /* o : Frequency group average gain to fade to */
+ Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx,
+ Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx,
+ Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 fadeout,
+ Word32 *L_Xavg, /* full scale average band amplitudes */
+#endif
+ Word8 *scratchBuffer);
+
+void spec_ana_fx(Word16 *xfp, Word16 *, Word32 *, Word16 *, Word16 *, const Word16, const Word16,
+ const Word16 *, const Word16, const Word16, Word16 maxLprot, Word16 maxPlocs, Word8 *scratchBuffer);
+
+void subst_spec_fx(const Word16 *, const Word32 *, Word16 *, const Word16, Word16 *, const Word16 *, const Word16,
+ const Word16 *, const Word16, Word16 *, const Word16 *, const Word16 *, const Word16 *, const Word16
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ ,const Word16,
+ Word16*,
+ const Word32 *
+#endif
+);
+
+void rec_frame_fx(Word16 * X, /* i : FFT spectrum */
+ Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain */
+ const Word16 output_frame, /* i : Frame length */
+ const Word16 Q, const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+
+ Word16 maxLprot, const Word16 *prevsynth, const Word16 Q_prevsynth,
+ Word8 * scratchBuffer);
+
+Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F);
+
+void hq_phase_ecu_fx(const Word16 *prevsynth, /* i : buffer of previously synthesized signal */
+ Word32 *L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */
+ Word16 *time_offs, /* i/o: Sample offset for consecutive frame losses*/
+ Word16 *X_sav, /* i/o: Stored spectrum of prototype frame */
+ Word16 *Q_spec, /* o: Q value of stored spectrum */
+ Word16 *num_p, /* i/o: Number of identified peaks */
+ Word16 *plocs, /* i/o: Peak locations */
+ Word32 *L_plocsi, /* i/o: Interpolated peak locations Q16 */
+ const Word16 env_stab, /* i : Envelope stability parameter */
+ const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */
+ const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */
+ const Word16 prev_bfi, /* i : indicating burst frame error */
+ Word16 old_is_transient[2], /* i/o : flags indicating noise generation */
+ Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients */
+ Word16 * mag_chg_gr, /* o: per band magnitude modifier incl burst attenuation */
+ Word16 * Xavg, /* i/o: Frequency group average gain to fade to */
+ Word16 * beta_mute, /* o : Factor for long-term mute */
+ const Word16 bwidth_fx, /* i : Encoded bandwidth */
+ const Word16 output_frame, /* i : frame length */
+ Word16 * seed_out_fxPtr, /* o: seed synch analysis */
+ Word16 * X_out, /* o: utput evolved spectrum */
+ const Word16 t_adv, /* i : time adjustment including time_offs */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ const Word16 * sp_ana_win, /* i : whr hamming window */
+ Word16 q_fx_old_exp, Word16 maxLprot, Word16 maxPlocs,
+ Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signal */
+ Word16 oold_Ltot_exp_fx, /*true exp of energy */
+ Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx,
+ Word16 old_xfp_w_E_exp_fx, /* exp of time signal */
+ Word16 old_Ltot_exp_fx, /*true exp of energy */
+ Word16 *old_grp_shape_fx,
+ Word16 margin_prev_synth, /* i: margin in prev_synth(16ms for first bfi , 3.75 ms for other bfi
+ frames ) , from plcAd.PhECU_margin_xfp */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ const Word16 fadeout, /*i: fadeout length indicator */
+ Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */
+#endif
+ Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */
+);
+
+Word16
+plc_xcorr_lc_fx(/* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */
+ Word16 *
+ pcmbuf_fx, /* NB should be an already dynamically upscaled buffer with about 0...1 bits margin */
+ Word16 max_len_pcm_plc, /* Q0 size of pcmbuf_fx */
+ Word16 pitch_int, /* Q0 in Fs, lag value to evaluate, corresponding to the current f0 fr pcm_buf */
+ Word16 fs_idx);
+
+void plc_phEcu_peak_locator_fx(const Word16 *, const Word16, Word16 *, Word16 *, const Word16, const Word16,
+ const Word16, Word16, Word8 *);
+
+Word16 plc_phEcu_find_ind_fx(const Word16 *, const Word16, const Word16);
+
+
+Word16 initQV(Word16 SR_idx, Word32 BR);
+
+void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 sqTargetBits,
+#ifdef ENABLE_HR_MODE
+ Word32 *gain,
+#else
+ Word16 *gain,
+#endif
+ Word16 *gain_e,
+ Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff,
+ Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode, Word16 regBits, Word16 frame_dms
+#endif
+);
+
+void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off,
+#ifdef ENABLE_HR_MODE
+ Word32 *gain,
+#else
+ Word16 *gain,
+#endif
+ Word16 *gain_e,
+ Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode, Word16 frame_dms
+#endif
+ );
+
+void processScalarQuant_fx(Word32 x[], Word16 x_e, Word16 xq[], Word16 L_frame, Word16 gain, Word16 gain_e);
+
+#ifdef ENABLE_HR_MODE
+void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target,
+ Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz,
+ Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode);
+#else
+void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt,
+ Word16 target,
+ Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz,
+ Word16 *codingdata, Word16 *lsbMode, Word16 mode);
+
+#endif /* ENABLE_HR_MODE */
+
+void processResidualCoding_fx(Word16 x_e, Word32 x[],
+#ifdef ENABLE_HR_MODE
+ Word32 xq[], Word32 gain,
+#else
+ Word16 xq[], Word16 gain,
+#endif
+ Word16 gain_e, Word16 L_spec, Word16 targetBits, Word16 nBits,
+ UWord8 *resBits, Word16 *numResBits
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+);
+
+void scale_signal24_fx(Word32 x[], /* i: time input signal */
+#ifdef ENABLE_HR_MODE
+ Word32 x_scaled[],
+#else
+ Word16 x_scaled[],
+#endif
+ Word16 *x_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 mdct_mem[],
+#else
+ Word16 mdct_mem[],
+#endif
+ Word16 mdct_mem_len,
+ Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[],
+ Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N,
+ Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale);
+
+void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer);
+
+/* al_fec.c */
+Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag);
+Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes);
+Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes);
+
+void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw,
+ void *scratch);
+
+int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw,
+ int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch);
+
+void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[],
+ Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 q_old_d_fx[], Word16 spec_inv_idx,
+ Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp,
+ Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf,
+ Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow);
+void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[],
+ Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi);
+void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e,
+ Word16 *pc_nbLostFramesInRow);
+void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e,
+ Word16 rframe, Word16 *BW_cutoff_idx_nf, Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx,
+ Word16 *prev_fac_ns_fx, Word16 fac, Word16 fac_e);
+void processPcApplyDamping_fx(Word32 x[], Word16 xLen, Word16 fac, Word16 spec_inv_idx);
+
+void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin);
+
+void idct16_fx(const Word16 *in, Word16 *out);
+
+void dct32_fx(const Word32 *in, Word32 *out);
+void idct32_fx(const Word32 *in, Word32 *out);
+void idct32_32_fx(const Word32 *in, Word32 *out);
+
+/* Functions used in arithmetic coder */
+
+void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit);
+void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits);
+
+void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes,
+ Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters, Word16 lsbMode, Word16 lastnz,
+ Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, Word16 BW_cutoff_idx, Word16 *ltpf_idx,
+ Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx);
+
+void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec,
+ Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters, Word16 *lsbMode,
+ Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx, Word16 *gg_idx,
+ Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 frame_dms);
+
+#ifdef ENABLE_PADDING
+int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled,
+ Word16 *total_padding, Word16 *np_zero);
+#endif
+
+Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask);
+
+/* setup_enc_lc3.c */
+int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels);
+void set_enc_frame_params(LC3PLUS_Enc *encoder);
+LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate);
+LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ , int32_t lfe_channel_array[]
+ );
+
+/* setup_dec_lc3.c */
+int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels);
+void set_dec_frame_params(LC3PLUS_Dec *decoder);
+LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes);
+LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ );
+
+int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext);
+LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int input_bytes, void **output, int bits_per_sample, void *scratch,
+ int bfi_ext);
+
+void *balloc(void *base, size_t *base_size, size_t size);
+
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms);
+#endif
+
+#endif
diff --git a/lib_lc3plus/imdct_fx.c b/lib_lc3plus/imdct_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..50ad2b257c6f2b9a9b3b4272c3c4e1929490b27b
--- /dev/null
+++ b/lib_lc3plus/imdct_fx.c
@@ -0,0 +1,387 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void ProcessingIMDCT(
+ Word32 y[], /* i: spectra data */
+ Word16 * y_e, /* i: spectral data exponent */
+#ifdef ENABLE_HR_MODE
+ const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+ Word32 mem[], /* i/o: overlap add memory */
+#else
+ const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+ Word16 mem[], /* i/o: overlap add memory */
+#endif
+ Word16 * mem_e, /* i/o: overlap add exponent */
+#ifdef ENABLE_HR_MODE
+ Word32 x[], /* o: time signal out */
+#else
+ Word16 x[], /* o: time signal out */
+#endif
+ Word16 wLen, /* i: window length */
+ Word16 N, /* i: block size */
+ Word16 memLen, /* i: overlap add buffer size */
+ Word16 frame_dms, /* i: frame size in ms */
+ Word16 concealMethod, /* i: concealment method */
+ Word16 bfi, /* i: bad frame indicator */
+ Word16 prev_bfi, /* i: previous bad frame indicator */
+ Word16 nbLostFramesInRow, /* i: number of consecutive lost frames */
+ AplcSetup *plcAd, /* i: advanced plc struct */
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+)
+{
+ Counter i;
+ Word16 o, z, m, s;
+ Word16 y_s, mem_s, max_bw;
+ Word32 L_tmp;
+ Word32 *workBuffer;
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Word16 o, z, m, s;
+ Word16 y_s, mem_s, max_bw;
+ Word32 L_tmp;
+ Counter i;
+ Word32 *workBuffer;
+ Word16 mem_i_win;
+ Word16 w_taper_win;
+ };
+ Dyn_Mem_In("ProcessingIMDCT", sizeof(struct _dynmem));
+#endif
+
+
+ test(); test(); test();
+ IF (sub(bfi, 1) != 0 || sub(concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0)
+ {
+ workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */
+
+ /* Init (constant per sample rate) */
+ z = 2 * N - wLen; /* number of leading zeros in window */
+ m = N >> 1; /* half block size */
+ o = m - z;
+ max_bw = 0;
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ max_bw = N;
+ }
+ else
+#endif
+ {
+ SWITCH (frame_dms)
+ {
+ case 25:
+ max_bw = MAX_BW >> 2; move16();
+ BREAK;
+ case 50:
+ max_bw = MAX_BW >> 1; move16();
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ max_bw = (MAX_BW >> 2) * 3; move16();
+ BREAK;
+#endif
+ case 100:
+ max_bw = MAX_BW; move16();
+ BREAK;
+ }
+ }
+
+ if (N > max_bw)
+ basop_memset(&y[max_bw], 0, (N - max_bw) * sizeof(*y));
+
+ /* Start Processing */
+ y_s = getScaleFactor32_0(y, N);
+ IF (sub(y_s, 32) < 0)
+ {
+ FOR (i = 0; i < N; i++)
+ {
+ y[i] = L_shl(y[i], y_s);
+ }
+ *y_e = sub(*y_e, y_s);
+#ifdef ENABLE_HR_MODE
+ dct_IV(y, y_e, N,
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ hrmode,
+# endif
+ workBuffer);
+#else
+ dct_IV(y, y_e, N, workBuffer);
+#endif
+ y_s = getScaleFactor32_lc3plus(y, N);
+ y_s = sub(y_s, 1);
+ *y_e = sub(*y_e, y_s + 3); /* mdct window is scaled by pow(2,x) */
+ /* N<=20 only happens for 2.5ms frames in NB */
+ if (sub(N, 20) <= 0)
+ {
+ *y_e = add(*y_e, 2);
+ }
+ else if (sub(N, 120) <= 0)
+ {
+ *y_e = add(*y_e, 1);
+ }
+ }
+ ELSE
+ {
+ *y_e = 0; move16();
+ }
+
+#ifdef ENABLE_HR_MODE
+ mem_s = getScaleFactor32_0(mem, memLen);
+#else
+ mem_s = getScaleFactor16_0(mem, memLen);
+#endif
+
+#ifdef ENABLE_HR_MODE
+ IF (sub(mem_s, 32) < 0)
+#else
+ IF (sub(mem_s, 16) < 0)
+#endif
+ {
+ mem_s = sub(mem_s, 1);
+ *mem_e = sub(*mem_e, mem_s);
+ }
+ ELSE
+ {
+ *mem_e = *y_e; move16();
+ }
+
+ s = sub(*mem_e, *y_e);
+
+ IF (s > 0)
+ {
+ y_s = sub(y_s, s);
+ *y_e = add(*y_e, s);
+ }
+ ELSE
+ {
+ mem_s = add(mem_s, s);
+ *mem_e = sub(*mem_e, s);
+ }
+
+ mem_s = s_max(mem_s, -31);
+ y_s = s_max(y_s, -31);
+
+ if (sub(y_s, 32) >= 0)
+ {
+ y_s = 0; move16();
+ }
+#ifdef ENABLE_HR_MODE
+ if (sub(mem_s, 32) >= 0)
+ {
+ mem_s = 0; move16();
+ }
+#else
+ if (sub(mem_s, 16) >= 0)
+ {
+ mem_s = 0; move16();
+ }
+#endif
+
+ UNUSED(prev_bfi);
+ UNUSED(nbLostFramesInRow);
+ UNUSED(plcAd);
+
+ { /* regular operation */
+ FOR (i = 0; i < o; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ L_tmp = L_sub(L_shl(mem[i], mem_s), Mpy_32_32_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z]));
+ x[i] = L_tmp;
+ move32();
+#else
+ L_tmp = L_sub(L_shl(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z]));
+ x[i] = round_fx(L_tmp);
+ move16();
+#endif
+ }
+ FOR (i = 0; i < m; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ L_tmp = L_add(L_shl(mem[i + o], mem_s), Mpy_32_32_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i]));
+ x[i + o] = L_tmp;
+ move32();
+#else
+ L_tmp = L_add(L_shl(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i]));
+ x[i + o] = round_fx(L_tmp);
+ move16();
+#endif
+ }
+ }
+
+ FOR (i = 0; i < m; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m - 1 - i]));
+ x[3 * m - z + i] = L_tmp;
+ move32();
+#else
+ L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m - 1 - i]));
+ x[3 * m - z + i] = round_fx(L_tmp);
+ move16();
+#endif
+ }
+
+ FOR (i = 0; i < m; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m + i]));
+ x[3 * m - z - 1 - i] = L_tmp;
+ move32();
+#else
+ L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m + i]));
+ x[3 * m - z - 1 - i] = round_fx(L_tmp);
+ move16();
+#endif
+ }
+
+#ifdef ENABLE_HR_MODE
+ basop_memmove(mem, &x[N], memLen * sizeof(Word32));
+#else
+ basop_memmove(mem, &x[N], memLen * sizeof(Word16));
+#endif
+
+ *mem_e = *y_e; move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+/* End Processing */
+
+void Processing_ITDA_WIN_OLA(
+ Word32 L_x_tda[], /* i: X_TDA buffer data = "y" DCT-IV output */
+ Word16 * y_e, /* i/o: x_tda input exponent "y_e" , x output exponent */
+#ifdef ENABLE_HR_MODE
+ const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#else
+ const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#endif
+ Word16 mem[], /* i/o: overlap add memory */
+ Word16 * mem_e, /* i/o: overlap add exponent */
+ Word16 x[], /* o: time signal out */
+ Word16 wLen, /* i: window length */
+ Word16 N, /* i: block size */
+ Word16 memLen /* i: overlap add buffer size */
+ )
+{
+ /* Declarations */
+ Word16 i, o, z, m, s;
+ Word16 y_s, mem_s;
+ Word32 L_tmp;
+ Word32 *L_y;
+ Word16 fs_idx, tmp_w, w_factor;
+ Word16 factorITDA[5]= { 25905 , 18318 , 22435 , 25905 , 31727};
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("Processing_ITDA_WIN_OLA", sizeof(struct {
+ Word16 i, o, z, m, s;
+ Word16 y_s, mem_s;
+ Word32 L_tmp;
+ Word32 *L_y;
+ }));
+#endif
+
+
+ /* Init (constants per sample rate) */
+ z = 2 * N - wLen; /* number of leading zeros in window */
+ m = N >> 1; /* half block size */
+ o = m - z;
+
+
+ L_y = L_x_tda; /* use same variables naming as in IMDCT for DCT-IV output signal y */
+
+ y_s = getScaleFactor32_lc3plus(L_y, N);
+
+ y_s = sub(y_s, 1); /* add 1 bit margin , y_s is now initial tda upscaling factor */
+
+
+ *y_e = sub(add(*y_e,1),y_s); /* handle W scale down by 2^(3) , as mdct synthesis window was upscaled by pow(2,x) x=2 for NB otherwise 3 */
+
+
+
+ mem_s = getScaleFactor16_0(mem, memLen);
+
+ IF (sub(mem_s, 16) < 0)
+ {
+ mem_s = sub(mem_s, 1); /* one bit margin */
+ *mem_e = sub(*mem_e, mem_s); /*adjusted mem exponent due to new scale */
+ }
+ ELSE
+ {
+ *mem_e = 0; move16();
+ }
+
+ s = sub(*mem_e, *y_e); /* */
+
+ IF (s > 0)
+ {
+ y_s = sub(y_s, s); /* new , reduced upshift of TDA in window application loop */
+ *y_e = add(*y_e, s); /* resulting new exp y_e for output signal */
+ }
+ ELSE
+ {
+ mem_s = add(mem_s, s); /* s negative or zero, new , decreased upshift of OLAmem in loop */
+ *mem_e = sub(*mem_e, s); /* resulting new exp mem_e for OLA_mem output signal */
+ }
+
+ fs_idx = mult(N,(Word16)(32768.0/99.0)); /* truncation needed , i.e no rounding can be applied here */
+ w_factor = factorITDA[fs_idx]; move16();
+ y_s = s_max(s_min(y_s, 31), -31);
+
+ FOR (i = 0; i < o; i++)
+ {
+ tmp_w = mult_r(extractW16(w[4 * m - 1 - i - z]), w_factor);
+ L_tmp = L_sub(L_shl_sat(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[m + i + z], y_s), tmp_w));
+ x[i] = round_fx_sat(L_tmp);
+ move16();
+ }
+
+ FOR (i = 0; i < m; i++)
+ {
+ tmp_w = mult_r(extractW16(w[3 * m - 1 - i]), w_factor);
+ L_tmp = L_add(L_shl_sat(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[2 * m - 1 - i], y_s), tmp_w));
+ x[i + o] = round_fx_sat(L_tmp);
+ move16();
+ }
+
+ FOR (i = 0; i < m; i++)
+ {
+ tmp_w = mult_r(extractW16(w[m - 1 - i]), w_factor);
+ L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w));
+ x[3 * m - z + i] = round_fx(L_tmp); move16();
+ }
+
+ FOR (i = 0; i < m; i++)
+ {
+ tmp_w = mult_r(extractW16(w[m + i]), w_factor);
+ L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w ));
+ x[3 * m - z - 1 - i] = round_fx(L_tmp); move16();
+ }
+
+ FOR (i = 0; i < memLen; i++)
+ {
+ mem[i] = x[N + i]; move16();
+ }
+ *mem_e = *y_e; move16(); /* set OLA mem exp to x_Fx exponent*/
+
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c
new file mode 100644
index 0000000000000000000000000000000000000000..120dd092907669f71e0f0dae0275dec0eef71d51
--- /dev/null
+++ b/lib_lc3plus/lc3.c
@@ -0,0 +1,426 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+#include "lc3.h"
+#include "setup_dec_lc3.h"
+#include "setup_enc_lc3.h"
+
+#define RETURN_IF(cond, error) \
+ if (cond) \
+ return (error)
+
+#ifdef SUBSET_NB
+#pragma message("- SUBSET_NB")
+#endif
+#ifdef SUBSET_WB
+#pragma message("- SUBSET_WB")
+#endif
+#ifdef SUBSET_SSWB
+#pragma message("- SUBSET_SSWB")
+#endif
+#ifdef SUBSET_SWB
+#pragma message("- SUBSET_SWB")
+#endif
+#ifdef SUBSET_FB
+#pragma message("- SUBSET_FB")
+#endif
+#ifdef SUBSET_UB
+#pragma message("- SUBSET_UB")
+#endif
+
+/* ensure api header constants are up to date */
+STATIC_ASSERT(LC3PLUS_MAX_SAMPLES >= MAX_LEN);
+STATIC_ASSERT(LC3PLUS_MAX_CHANNELS >= MAX_CHANNELS);
+STATIC_ASSERT(LC3PLUS_MAX_BYTES >= BYTESBUFSIZE);
+STATIC_ASSERT(LC3PLUS_ENC_MAX_SIZE >= ENC_MAX_SIZE);
+STATIC_ASSERT(LC3PLUS_DEC_MAX_SIZE >= DEC_MAX_SIZE);
+STATIC_ASSERT(LC3PLUS_ENC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_ENC_TOT);
+STATIC_ASSERT(LC3PLUS_DEC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_DEC_TOT);
+STATIC_ASSERT(PLC_FADEOUT_IN_MS >= 20);
+
+
+/* misc functions ************************************************************/
+
+int lc3plus_version(void)
+{
+ return LC3PLUS_VERSION;
+}
+
+int lc3plus_channels_supported(int channels)
+{
+ return channels >= 1 && channels <= MAX_CHANNELS;
+}
+
+int lc3plus_samplerate_supported(int samplerate)
+{
+ switch (samplerate)
+ {
+#ifdef SUBSET_NB
+ case 8000: return 1;
+#endif
+#ifdef SUBSET_WB
+ case 16000: return 1;
+#endif
+#ifdef SUBSET_SSWB
+ case 24000: return 1;
+#endif
+#ifdef SUBSET_SWB
+ case 32000: return 1;
+#endif
+#ifdef SUBSET_FB
+ case 44100: return 1;
+ case 48000: return 1;
+#endif
+#ifdef ENABLE_HR_MODE
+ case 96000: return 1;
+#endif
+ default: return 0;
+ }
+}
+
+static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode)
+{
+ switch ((int)plc_mode)
+ {
+ case LC3PLUS_PLC_ADVANCED: /* fallthru */
+ return 1;
+ default: return 0;
+ }
+}
+
+static int lc3plus_frame_size_supported(int frame_dms)
+{
+ switch (frame_dms)
+ {
+ case 25: /* fallthru */
+ case 50: /* fallthru */
+#ifdef CR8_G_ADD_75MS
+ case 75: /* fallthru */
+#endif
+ case 100:
+ return 1;
+ default: return 0;
+ }
+}
+
+static int null_in_list(void **list, int n)
+{
+ while (--n >= 0)
+ RETURN_IF(list[n] == NULL, 1);
+ return 0;
+}
+
+/* return pointer to aligned base + base_size, *base_size += size + 4 bytes align */
+void *balloc(void *base, size_t *base_size, size_t size)
+{
+ uintptr_t ptr = ((uintptr_t)base + *base_size + 3) & ~3;
+ assert((uintptr_t)base % 4 == 0); /* base must be 4-byte aligned */
+ *base_size = (*base_size + size + 3) & ~3;
+ return (void *)ptr;
+}
+
+int32_t lc3_enc_supported_lfe(void)
+{
+ return 1;
+}
+
+/* encoder functions *********************************************************/
+
+LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ , int32_t lfe_channel_array[]
+ )
+{
+ int ch = 0;
+
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR);
+ RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR);
+ RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR);
+#ifdef ENABLE_HR_MODE
+ RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR);
+#endif
+
+ for (ch = 0; ch < channels; ch++)
+ {
+ RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED);
+ }
+
+#ifdef ENABLE_HR_MODE
+ return FillEncSetup(encoder, samplerate, channels, hrmode
+ , lfe_channel_array
+ ); /* real bitrate check happens here */
+#else
+ return FillEncSetup(encoder, samplerate, channels
+ , lfe_channel_array
+ ); /* real bitrate check happens here */
+#endif
+}
+
+int lc3plus_enc_get_size(int samplerate, int channels)
+{
+ RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0);
+ RETURN_IF(!lc3plus_channels_supported(channels), 0);
+ return alloc_encoder(NULL, samplerate, channels);
+}
+
+int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder)
+{
+ int size = 0;
+ RETURN_IF(encoder == NULL, 0);
+
+#ifdef ENABLE_HR_MODE
+ size = 47 * MAX(encoder->frame_length, 160) + 64;
+#else
+ size = 14 * MAX(encoder->frame_length, 160) + 64;
+#endif
+ assert(size <= LC3PLUS_ENC_MAX_SCRATCH_SIZE);
+ return size;
+}
+
+int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder)
+{
+ RETURN_IF(encoder == NULL, 0);
+ return encoder->frame_length;
+}
+
+int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder)
+{
+ RETURN_IF(encoder == NULL, 0);
+ return (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in);
+}
+
+int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder)
+{
+ int ch = 0, totalBytes = 0;
+ RETURN_IF(encoder == NULL, 0);
+ RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR);
+
+ for (ch = 0; ch < encoder->channels; ch++)
+ {
+ totalBytes += encoder->channel_setup[ch]->targetBytes;
+ }
+
+ int bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms;
+
+ if (encoder->fs_in == 44100)
+ {
+ int rem = bitrate % 480;
+ bitrate = ((bitrate - rem) / 480) * 441 + (rem * 441) / 480;
+ }
+
+ return bitrate;
+}
+
+LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate)
+{
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF(bitrate <= 0, LC3PLUS_BITRATE_ERROR);
+ return update_enc_bitrate(encoder, bitrate);
+}
+
+int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder)
+{
+ RETURN_IF(encoder == NULL, 0);
+ return encoder->frame_length - 2 * encoder->la_zeroes;
+}
+
+LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode)
+{
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR);
+ encoder->epmode = epmode;
+ return encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK;
+}
+
+LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr)
+{
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF((unsigned)epmr > LC3PLUS_EPMR_HIGH, LC3PLUS_EPMR_ERROR);
+ encoder->epmr = epmr;
+ return LC3PLUS_OK;
+}
+
+LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms)
+{
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR);
+ RETURN_IF(encoder->lc3_br_set, LC3PLUS_BITRATE_SET_ERROR);
+ encoder->frame_dms = frame_dms;
+ set_enc_frame_params(encoder);
+ return LC3PLUS_OK;
+}
+
+
+LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth)
+{
+ RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR);
+ Word32 effective_fs = encoder->fs_in;
+ if (encoder->bandwidth != bandwidth) {
+ if (encoder->fs_in > 40000) {
+ effective_fs = 40000;
+ }
+ if ((bandwidth * 2) > effective_fs) {
+ return LC3PLUS_BW_WARNING;
+ }
+ else {
+ encoder->bandwidth = bandwidth;
+ encoder->bandwidth_preset = bandwidth;
+ encoder->bw_ctrl_active = 1;
+ update_enc_bitrate(encoder, encoder->bitrate);
+ }
+ }
+ return LC3PLUS_OK;
+}
+
+
+static LC3PLUS_Error lc3plus_enc(LC3PLUS_Enc *encoder, void **input_samples, int bitdepth, void *output_bytes, int *num_bytes,
+ void *scratch)
+{
+ RETURN_IF(!encoder || !input_samples || !output_bytes || !num_bytes || !scratch, LC3PLUS_NULL_ERROR);
+ RETURN_IF(null_in_list(input_samples, encoder->channels), LC3PLUS_NULL_ERROR);
+ RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR);
+ RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR);
+ *num_bytes = Enc_LC3PLUS(encoder, input_samples, bitdepth, output_bytes, scratch, *num_bytes == -1);
+
+ assert(*num_bytes == lc3plus_enc_get_num_bytes(encoder));
+ return LC3PLUS_OK;
+}
+
+LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch)
+{
+ return lc3plus_enc(encoder, (void **)input_samples, 16, output_bytes, num_bytes, scratch);
+}
+
+LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch)
+{
+ return lc3plus_enc(encoder, (void **)input_samples, 24, output_bytes, num_bytes, scratch);
+}
+
+/* decoder functions *********************************************************/
+
+LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+)
+{
+ RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR);
+ RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR);
+ RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), LC3PLUS_PLCMODE_ERROR);
+#ifdef ENABLE_HR_MODE
+ RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR);
+#endif
+
+ return FillDecSetup(decoder, samplerate, channels, plc_mode
+#ifdef ENABLE_HR_MODE
+ , hrmode
+#endif
+ );
+}
+
+int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode)
+{
+ RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0);
+ RETURN_IF(!lc3plus_channels_supported(channels), 0);
+ RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), 0);
+ return alloc_decoder(NULL, samplerate, channels);
+}
+
+int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder)
+{
+ int size = 0;
+ RETURN_IF(decoder == NULL, 0);
+
+#ifdef ENABLE_HR_MODE
+ size = 30 * DYN_MAX_LEN(decoder->fs) + 2866;
+ size += 4 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 16 * DYN_MAX_LEN(decoder->fs);
+#else
+ size = 12 * DYN_MAX_LEN(decoder->fs) + 752;
+ size += 2 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 8 * DYN_MAX_LEN(decoder->fs);
+ size += 3720;
+#endif
+
+ assert(size <= LC3PLUS_DEC_MAX_SCRATCH_SIZE);
+ return size;
+}
+
+LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled)
+{
+ RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR);
+ decoder->ep_enabled = ep_enabled != 0;
+ decoder->epmr = LC3PLUS_EPMR_ZERO;
+ return LC3PLUS_OK;
+}
+
+int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder)
+{
+ RETURN_IF(decoder == NULL, 0);
+ return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF;
+}
+
+int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder)
+{
+ RETURN_IF(decoder == NULL, 0);
+ return decoder->error_report >> 11;
+}
+
+LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder)
+{
+ RETURN_IF(decoder == NULL, LC3PLUS_EPMR_ZERO);
+ return (LC3PLUS_EpModeRequest)decoder->epmr;
+}
+
+LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms)
+{
+ RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR);
+ RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR);
+ RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR);
+
+ decoder->frame_dms = frame_dms;
+ set_dec_frame_params(decoder);
+ return LC3PLUS_OK;
+}
+
+
+int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder)
+{
+ RETURN_IF(decoder == NULL, 0);
+ return decoder->frame_length;
+}
+
+int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder)
+{
+ RETURN_IF(decoder == NULL, 0);
+ return decoder->frame_length - 2 * decoder->la_zeroes;
+}
+
+static LC3PLUS_Error lc3plus_dec(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, void **output_samples, int bitdepth,
+ void *scratch, int bfi_ext)
+{
+ RETURN_IF(!decoder || !input_bytes || !output_samples || !scratch, LC3PLUS_NULL_ERROR);
+ RETURN_IF(null_in_list(output_samples, decoder->channels), LC3PLUS_NULL_ERROR);
+ RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR);
+ return Dec_LC3PLUS(decoder, input_bytes, num_bytes, output_samples, bitdepth, scratch, bfi_ext);
+}
+
+LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch, int bfi_ext)
+{
+ return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 16, scratch, bfi_ext);
+}
+
+LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch, int bfi_ext)
+{
+ return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 24, scratch, bfi_ext);
+}
diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h
new file mode 100644
index 0000000000000000000000000000000000000000..64d8cc590c5fc66c9fa711086e86ced5be081e72
--- /dev/null
+++ b/lib_lc3plus/lc3.h
@@ -0,0 +1,520 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+/*! \file lc3.h
+ * This header provides the API for LC3plus.
+ *
+ * This library is targeting devices with extreme memory limitations, so memory management
+ * must be handeled by the user. This includes allocating memory for the structs and scratch
+ * memory. The structs are persistent between function calls. The scratch memory is working
+ * memory that does not persist between function calls.
+ *
+ * The amount of memory needed for various configurations can be obtained from the lc3plus_*_get_size
+ * and lc3plus_*_get_scratch_size functions. If memory usage is not a concern the LC3PLUS_*_MAX_SIZE
+ * LC3PLUS_*_MAX_SCRATCH_SIZE macros can be used for all configurations.
+ *
+ * Depending on the build configuration some functions might not be available.
+ */
+
+#ifndef LC3PLUS_H
+#define LC3PLUS_H
+
+#define ENABLE_HR_MODE
+
+#ifndef _MSC_VER
+#include
+#else
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+#endif
+
+/*! Construct version number from major/minor/micro values. */
+#define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro))
+
+/*! Version number to ensure header and binary are matching. */
+#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 3)
+
+/*! Maximum number of supported channels. The actual binary might support
+ * less, use lc3plus_channels_supported() to check. */
+#define LC3PLUS_MAX_CHANNELS 2
+
+/*! Maximum number of samples per channel that can be stored in one LC3plus frame. */
+#ifdef ENABLE_HR_MODE
+#define LC3PLUS_MAX_SAMPLES 960
+#else
+#define LC3PLUS_MAX_SAMPLES 480
+#endif
+
+/*! Maximum number of bytes of one LC3plus frame. */
+#ifdef ENABLE_HR_MODE
+#define LC3PLUS_MAX_BYTES (625 * LC3PLUS_MAX_CHANNELS)
+#else
+#define LC3PLUS_MAX_BYTES 870
+#endif
+
+/*! Maximum size needed to store encoder state. */
+#ifdef ENABLE_HR_MODE
+#define LC3PLUS_ENC_MAX_SIZE 12628
+#else
+#define LC3PLUS_ENC_MAX_SIZE 7226
+#endif
+
+/*! Maximum size needed to store decoder state. */
+#ifdef ENABLE_HR_MODE
+#define LC3PLUS_DEC_MAX_SIZE 42488
+#else
+#define LC3PLUS_DEC_MAX_SIZE 28446
+#endif
+
+/*! Maximum scratch size needed by lc3plus_enc16() or lc3plus_enc24().*/
+#ifdef ENABLE_HR_MODE
+# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 45624
+#else
+# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 6784
+#endif
+
+/*! Maximum scratch size needed by lc3plus_dec16() or lc3plus_dec24(). */
+#ifdef ENABLE_HR_MODE
+#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 59768
+#else
+#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 27474
+#endif
+/*! Decoder packet loss concealment mode */
+typedef enum
+{
+ LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */
+} LC3PLUS_PlcMode;
+
+/*! Error protection mode. LC3PLUS_EP_ZERO differs to LC3PLUS_EP_OFF in that
+ * errors can be detected but not corrected. */
+typedef enum
+{
+ LC3PLUS_EP_OFF = 0, /*!< Error protection is disabled */
+ LC3PLUS_EP_ZERO = 1, /*!< Error protection with 0 bit correction */
+ LC3PLUS_EP_LOW = 2, /*!< Error protection correcting one symbol per codeword */
+ LC3PLUS_EP_MEDIUM = 3, /*!< Error protection correcting two symbols per codeword */
+ LC3PLUS_EP_HIGH = 4 /*!< Error protection correcting three symbols per codeword */
+} LC3PLUS_EpMode;
+
+/*! Error protection mode request. On the encoder sidem, LC3PLUS_EPMR_ZERO to LC3PLUS_EPMR_HIGH
+ * can be set. The decoder returns mode requests with different confidences. */
+typedef enum
+{
+ LC3PLUS_EPMR_ZERO = 0, /*!< Request no error correction. High confidence if returned by decoder. */
+ LC3PLUS_EPMR_LOW = 1, /*!< Request low error correction. High confidence if returned by decoder. */
+ LC3PLUS_EPMR_MEDIUM = 2, /*!< Request medium error correction. High confidence if returned by decoder. */
+ LC3PLUS_EPMR_HIGH = 3, /*!< Request high error correction. High confidence if returned by decoder. */
+ LC3PLUS_EPMR_ZERO_MC = 4, /*!< No error correction requested, medium confidence. */
+ LC3PLUS_EPMR_LOW_MC = 5, /*!< Low error correction requested, medium confidence. */
+ LC3PLUS_EPMR_MEDIUM_MC = 6, /*!< Medium error correction requested, medium confidence. */
+ LC3PLUS_EPMR_HIGH_MC = 7, /*!< High error correction requested, medium confidence. */
+ LC3PLUS_EPMR_ZERO_NC = 8, /*!< No error correction requested, unvalidated. */
+ LC3PLUS_EPMR_LOW_NC = 9, /*!< Low error correction requested, unvalidated. */
+ LC3PLUS_EPMR_MEDIUM_NC = 10, /*!< Medium error correction requested, unvalidated. */
+ LC3PLUS_EPMR_HIGH_NC = 11 /*!< High error correction requested, unvalidated. */
+} LC3PLUS_EpModeRequest;
+
+/*! Error codes returned by functions. */
+typedef enum
+{
+ LC3PLUS_OK = 0, /*!< No error occurred */
+ LC3PLUS_ERROR = 1, /*!< Function call failed */
+ LC3PLUS_DECODE_ERROR = 2, /*!< Frame failed to decode and was concealed */
+ LC3PLUS_NULL_ERROR = 3, /*!< Pointer argument is null */
+ LC3PLUS_SAMPLERATE_ERROR = 4, /*!< Invalid samplerate value */
+ LC3PLUS_CHANNELS_ERROR = 5, /*!< Invalid channels value */
+ LC3PLUS_BITRATE_ERROR = 6, /*!< Invalid bitrate value */
+ LC3PLUS_NUMBYTES_ERROR = 7, /*!< Invalid num_bytes value */
+ LC3PLUS_EPMODE_ERROR = 8, /*!< Invalid plc_method value */
+ LC3PLUS_FRAMEMS_ERROR = 9, /*!< Invalid epmode value */
+ LC3PLUS_ALIGN_ERROR = 10, /*!< Invalid frame_ms value */
+ LC3PLUS_HRMODE_ERROR = 11, /*!< Unaligned pointer */
+ LC3PLUS_BITRATE_UNSET_ERROR = 12, /*!< Invalid epmr value */
+ LC3PLUS_BITRATE_SET_ERROR = 13, /*!< Invalid usage of hrmode, sampling rate and frame size */
+ LC3PLUS_HRMODE_BW_ERROR = 14, /*!< Function called before bitrate has been set */
+ LC3PLUS_PLCMODE_ERROR = 15, /*!< Function called after bitrate has been set */
+ LC3PLUS_EPMR_ERROR = 16, /*!< Invalid external bad frame index */
+ LC3PLUS_PADDING_ERROR = 17, /*!< Incorrect padding value */
+ FRAMESIZE_ERROR = 18, /*!< Incorrect frame size during decoding */
+ LC3PLUS_LFE_MODE_NOT_SUPPORTED = 19, /*!< LFE support not available */
+
+ /* START WARNING */
+ LC3PLUS_WARNING = 20,
+ LC3PLUS_BW_WARNING = 21 /*!< Invalid bandwidth cutoff frequency */
+
+} LC3PLUS_Error;
+
+typedef struct LC3PLUS_Enc LC3PLUS_Enc; /*!< Opaque encoder struct. */
+typedef struct LC3PLUS_Dec LC3PLUS_Dec; /*!< Opaque decoder struct. */
+
+/*! \addtogroup Misc
+ * \{ */
+
+/*! Test LFE mode support.
+ *
+ * Tests the support of the LFE mode.
+ *
+ * \return 1 for true, 0 for false.
+ */
+int32_t lc3_enc_supported_lfe(void);
+
+/*! Return library version number. It should match LC3PLUS_VERSION. */
+int lc3plus_version(void);
+
+/*! Tests if the library supports number of channels.
+ *
+ * \param[in] channels Number of channels.
+ * \return 1 for true, 0 for false.
+ */
+int lc3plus_channels_supported(int channels);
+
+/*! Tests if the library supports a sampling rate.
+ *
+ * \param[in] samplerate Sampling rate
+ * \return 1 for true, 0 for false
+ */
+int lc3plus_samplerate_supported(int samplerate);
+
+/*! \}
+ * \addtogroup Encoder
+ * \{ */
+
+/*!
+ * Initialize LC3plus encoder.
+ *
+ * This function is used to fill a user-allocated encoder struct. This is typically
+ * called once for a samplerate / channel configuration. After init and before encoding
+ * the first frame you must call lc3plus_enc_set_bitrate().
+ *
+ * \param[out] encoder Pointer to allocated encoder memory. It must have a size provided
+ * by lc3plus_enc_get_size() for matching samplerate / channels
+ * configuration or LC3PLUS_ENC_MAX_SIZE.
+ * \param[in] channels Number of channels.
+ * \param[in] samplerate Input sampling rate. Allowed sampling rates are:
+ * 8000, 16000, 24000, 32000, 44100, 48000
+ * \param[in] hrmode High resolution mode.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ , int32_t lfe_channel_array[]
+ );
+
+/*!
+ * Encode LC3plus frame with 16 bit input.
+ *
+ * Each call consumes a fixed number of samples. The number of input samples
+ * can be obtained from lc3plus_enc_get_input_samples().
+ *
+ * \param[in] encoder Encoder handle initialized by lc3plus_enc_init().
+ * \param[in] input_samples Input samples. The left channel is stored in input_samples[0],
+ * the right channel in input_samples[1]. The input is not changed
+ * by the encoder.
+ * \param[out] output_bytes Output buffer. It must have a at least lc3plus_enc_get_num_bytes()
+ * or at most LC3PLUS_MAX_BYTES.
+ * \param[out] num_bytes Number of bytes written to output_bytes.
+ * \param scratch A pointer to an allocated work buffer of at least
+ * lc3plus_enc_get_scratch_size() or at most LC3PLUS_ENC_SCRATCH_SIZE bytes.
+ * The buffer does not have to persist, so it can be used for other
+ * purposes in between calls.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch);
+
+/*! Encode LC3plus frame with 24 bit input.
+ *
+ * The input samples are expected to be 24-bit values, sign-extended to 32-bit.
+ * See lc3plus_enc16() for parameter documentation.
+ */
+LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch);
+
+/*! Get the size of the LC3plus encoder struct for a samplerate / channel configuration.
+ * If memory is not restricted LC3PLUS_ENC_MAX_SIZE can be used for all configurations.
+ *
+ * \param[in] samplerate Sampling rate.
+ * \param[in] channels Number of channels.
+ * \return Size in bytes or 0 on error.
+ */
+int lc3plus_enc_get_size(int samplerate, int channels);
+
+/*! Get the size of the scratch buffer required by lc3plus_enc16() or lc3plus_enc24() for the current
+ * encoder configuration. If memory is not restricted, LC3PLUS_ENC_MAX_SCRATCH_SIZE can be used for
+ * all configurations.
+ *
+ * \param[in] encoder Encoder handle.
+ * \return Size in bytes or 0 on error.
+ */
+int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder);
+
+/*! Get number of samples per channel expected by lc3plus_enc16() or lc3plus_enc24().
+ *
+ * \param[in] encoder Encoder handle.
+ * \return Number of samples or 0 on error.
+ */
+int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder);
+
+/*! Get real internal bitrate of the encoder. It might differ from the requested bitrate due
+ * to error protection or 44.1 kHz input.
+ *
+ * \param[in] encoder Encoder handle.
+ * \return Bitrate in bits per second or 0 on error.
+ */
+int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder);
+
+/*! Get the maximum number of bytes produced by lc3plus_enc16() or lc3plus_enc24() for the current
+ * bitrate. It should be equal to the num_bytes output of lc3plus_enc16().
+ *
+ * \param[in] encoder Encoder handle.
+ * \return Size in bytes or 0 on error.
+ */
+int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder);
+
+/*! Set encoder bitrate for all channels.
+ * This function must be called at least once before encoding the first frame, but
+ * after other configuration functions such as lc3plus_enc_set_frame_dms().
+ *
+ * Recommended bitrates for input sampling rates with 10 ms framing:
+ * kHz | kbps
+ * --------|-----
+ * 8 | 24
+ * 16 | 32
+ * 24 | 48
+ * 32 | 64
+ * 44.1/48 | 80(voice) 128(music)
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] bitrate Bitrate in bits per second.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate);
+
+/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF.
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] lfe LFE mode flag
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_lfe(LC3PLUS_Enc* encoder, int lfe);
+
+/*! Get the encoder delay in number of samples.
+ *
+ * \param[in] encoder Encoder handle.
+ * \return Encoder in samples or 0 on error.
+ */
+int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder);
+
+/*! Set the frame length for LC3plus encoder in deci milliseconds.
+ * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned.
+ * This function must be called before lc3plus_enc_set_bitrate(). The decoder must be
+ * configured with lc3plus_dec_set_frame_dms() with the same value.
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] frame_ms Frame length in ms.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms);
+
+/*! Set error protection mode. The default is LC3PLUS_EP_OFF. It is possible to switch between
+ * different modees during encoding. Dynamic switching is only allowed between LC3PLUS_EP_ZERO,
+ * LC3PLUS_EP_LOW, LC3_EP_MEDIUM, and LC3PLUS_EP_HIGH. The the decoder must be notified with
+ * lc3plus_dec_set_ep_enabled() to expect protected data if epmode is other than LC3PLUS_EP_OFF.
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] epmode Error protection mode.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode);
+
+/*! Sets error protection mode request transmitted in each channel encoded frame.
+ * The channel coder includes an error protection mode request (EPMR) in every frame.
+ * The EPMR takes value 0, 1, 2, and 3 which request ep modes 1, 2, 3, and 4 from the
+ * decoding device. The EPMR can be retrieved from the channel decoder via the interface
+ * routine lc3plus_dec_get_ep_mode_request().
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] epmr Error Protection Mode Request
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr);
+
+/*! Set encoder bandwidth to a different value. All frequency bins above the cutoff
+ * frequency are cut off. Allowed frequencies are: 4 kHz, 8 kHz, 12 kHz, 16 kHz and 24 kHz.
+ *
+ * \param[in] encoder Encoder handle.
+ * \param[in] bandwidth Cutoff Frequency in Hz
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth);
+
+/*! \}
+ * \addtogroup Decoder
+ * \{ */
+
+
+/*!
+ * Initialize LC3plus decoder.
+ *
+ * This function is used to fill a user-allocated decoder struct. This is typically
+ * called once for a samplerate / channel / plc_mode configuration.
+ *
+ * The samplerate and channel arguments must have the same values that were used for encoding.
+ * LC3plus does not provide a signalling scheme, transporting these values is the responsibility
+ * of the application.
+ *
+ * \param[out] decoder Pointer to decoder memory. It must have as size of least
+ * lc3plus_dec_get_size() or at most LC3PLUS_DEC_MAX_SIZE.
+ * \param[in] samplerate Bitstream sampling rate.
+ * \param[in] channels Bitstream number of channels.
+ * \param[in] plc_mode Packet loss concealment mode.
+ * \param[in] hrmode High resolution mode mode.
+ *
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ );
+
+/*!
+ * Decode compressed LC3plus frame to 16 bit PCM output.
+ *
+ * Each call decodes a fixed number of samples. Use lc3plus_dec_get_output_samples() to obtain this
+ * number. When the input is corrupted and can not be decoded, LC3PLUS_DECODE_ERROR is returned and
+ * packet loss concealment is applied, so the output is still usable.
+ * If error protection is enabled and the errors can be corrected the frame is corrected and
+ * normally decoded. Use lc3plus_dec_get_error_report() to check if errors were corrected.
+ *
+ * \param[in] decoder Decoder initialized by lc3plus_dec_init().
+ * \param[in] input_bytes Input bytes. If error protection is enabled the input bytes can be
+ * altered when error correction is applied. This is why this buffer
+ * must be writable.
+ * \param[in] num_bytes Number of valid bytes in input_bytes. To signal a lost frame and
+ * generate concealment output this value must be set to 0.
+ * \param[out] output_samples Array of pointers to output channel buffers. Each channel buffer
+ * should provide enough space to hold at most LC3PLUS_MAX_SAMPLES. The
+ * left channel is stored in output_samples[0], the right channel in
+ * output_samples[1].
+ * \param scratch A pointer to an allocated work buffer of at least
+ * lc3plus_dec_get_scratch_size() or at most LC3PLUS_DEC_MAX_SCRATCH_SIZE
+ * bytes. The scratch buffer does not have to persist, so it can be
+ * used for other purposes in between calls.
+ * \return Returns LC3PLUS_OK on success or appropriate error code. Note there is
+ * a special case for LC3PLUS_DECODE_ERROR where the output is still valid.
+ */
+LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch,
+ int bfi_ext);
+
+/*! Decode compressed LC3plus frame to 24 bit PCM output.
+ *
+ * The output samples are 24-bit values, sign-extended to 32-bit.
+ * See lc3plus_dec16() for parameter documentation.
+ */
+LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch,
+ int bfi_ext);
+
+/*! Get the size of the LC3plus decoder struct for a samplerate / channel / plc_mode configuration.
+ * If memory is not restricted LC3PLUS_DEC_MAX_SIZE can be used for all configurations.
+ *
+ * \param[in] channels Number of channels.
+ * \param[in] samplerate Sampling rate.
+ * \param[in] plc_mode Packet loss concealment mode.
+ * \return Size in bytes or 0 on error.
+ */
+int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode);
+
+/*! Get the size of the scratch buffer required by lc3plus_dec16() or lc3plus_dec24() for the current
+ * decoder configuration. If memory is not restricted LC3PLUS_DEC_MAX_SCRATCH_SIZE can be used for
+ * all configurations.
+ *
+ * \param[in] decoder Decoder handle.
+ * \return Size in bytes or 0 on error.
+ */
+int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder);
+
+/*! Get the number of samples per channel produced by lc3plus_dec16() or lc3plus_dec24().
+ *
+ * \param[in] decoder Decoder handle.
+ * \return Number of samples or 0 on error.
+ */
+
+int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder);
+
+/*! Get the decoder delay in number of samples.
+ *
+ * \param[in] decoder Decoder handle.
+ * \return Delay in samples or 0 on error.
+ */
+int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder);
+
+/*! Set the frame length for LC3plus decoder in deci milliseconds.
+ * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned.
+ * This only works correcly if the encoder was configured with the same vale.
+ *
+ * \param[in] decoder Decoder handle.
+ * \param[in] frame_ms Frame length in ms.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_ms);
+
+/*! Enable or disable error protection. Default value is 0 (disabled). If error protection is
+ * enabled, the decoder expects that the frames were encoded with error protection mode
+ * LC3PLUS_EP_ZERO or higher.
+ *
+ * \param[in] decoder Decoder handle.
+ * \param[in] ep_enabled 1 (or any nonzero) for true, 0 for false.
+ * \return LC3PLUS_OK on success or appropriate error code.
+ */
+LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled);
+
+/*! Retrieves the error protection mode reqeust from channel decoder.
+ *
+ * The return value encodes both the error protection mode request (EPMR)
+ * and the confidence of the method by which it was retrieved.
+ *
+ * The requested error protection mode is (epmr % 4) + 1, where epmr is the
+ * function's return value. The confidence is specified as follows.
+ *
+ * Confidence | Range
+ * -----------|-------------
+ * high | 0 <= epmr < 4
+ * medium | 4 <= epmr < 8
+ * no | 8 <= epmr < 12
+ *
+ * When receiving stereo content of separately channel encoded audio frames the
+ * return value is the minimum of two values retrieved from the individual channels.
+ *
+ * \param[in] decoder Decoder handle.
+ * \return Error protection mode reqeust.
+ */
+LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder);
+
+/*! Get the number of corrected bit errors in the last decoded frame. This only works if
+ * error protection is active. If the number of errors is greater than the current error
+ * protection mode can correct, -1 is returned. If the last frame had no errors or the
+ * decoder handle is NULL, 0 is returned,
+ *
+ * \param[in] decoder Decoder handle.
+ * \return Number of corrected bits or -1. See description for details.
+ */
+int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder);
+/*! This function returns an set of flags indicating whether the last frame
+ * would have been channel decodable in epmode m, m ranging from 1 to 4. Note that
+ * this information is not available in case the last frame was not channel
+ * decodable in which case the return value is 0. If the last frame would have
+ * been decodable in epmode m, m-1th of the return value will be 1.
+ * Otherwise, if the frame would not have been decodable or if this information
+ * cannot be retrieved, the m-1th bit of the return value will be 0.
+ */
+int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder);
+
+/*! \} */
+#endif /* LC3plus */
diff --git a/lib_lc3plus/levinson_fx.c b/lib_lc3plus/levinson_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..9003173d04594dfe09c4d408b100883e7ec15cfc
--- /dev/null
+++ b/lib_lc3plus/levinson_fx.c
@@ -0,0 +1,160 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer)
+{
+
+ Word32 *lpc_tmp;
+ Word32 rc32, err, sum;
+ Word16 shift, s, inv;
+ Counter n, m;
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processLevinson_fx", sizeof(struct {
+ Word32 *lpc_tmp;
+ Word32 rc32, err, sum;
+ Word16 shift, s, inv;
+ Counter n, m;
+ Word32 params[2];
+ }));
+#endif
+
+ lpc_tmp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * (M_LTPF + 1) = 100 bytes */
+
+ /* Init Prediction Error */
+ err = ac[0]; move32();
+ shift = 0; move16();
+
+ /* LPC Coefficient 0 */
+ lpc[0] = 0x8000000; move32();
+
+ /* Reflection Coefficient 0 */
+ IF (ac[0] != 0)
+ {
+ inv = div_s(16383, extract_h(ac[0]));
+ rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(ac[1]), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(ac[0], inv)), inv)), 2);
+ }
+ ELSE
+ {
+ rc32 = 0; move32();
+ }
+ if (ac[1] > 0)
+ {
+ rc32 = L_negate(rc32);
+ }
+ if (rc != NULL)
+ {
+ rc[0] = round_fx(rc32); move16();
+ }
+
+ /* LPC Coefficient 1 */
+ lpc[1] = L_shr_pos(rc32, 4); move32();
+
+ FOR (n = 2; n <= N; n++)
+ {
+ /* Update Prediction Error */
+ err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32)));
+ s = norm_l(err);
+ err = L_shl_pos(err, s);
+ shift = add(shift, s);
+
+ /* Reflection Coefficient n-1 */
+ sum = Mpy_32_32_lc3plus(ac[1], lpc[n - 1]);
+ FOR (m = 2; m < n; m++)
+ {
+ sum = L_add(sum, Mpy_32_32_lc3plus(ac[m], lpc[n - m]));
+ }
+
+ sum = L_add(L_shl_pos(sum, 4), ac[n]);
+ IF (err != 0)
+ {
+ inv = div_s(16383, extract_h(err));
+ rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(sum), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(err, inv)), inv)), 2);
+ }
+ ELSE
+ {
+ rc32 = 0;
+ }
+ if (sum > 0)
+ {
+ rc32 = L_negate(rc32);
+ }
+ rc32 = L_shl(rc32, shift);
+ if (rc != NULL)
+ {
+ rc[n - 1] = round_fx(rc32); move16();
+ }
+
+/* Recompute LPC Coefficients up to n-1 */
+ FOR (m = 1; m < n; m++)
+ {
+ lpc_tmp[m] = L_add(lpc[m], Mpy_32_32_lc3plus(rc32, lpc[n - m])); move32();
+ }
+
+ basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32));
+
+ /* LPC Coefficient n */
+ lpc[n] = L_shr_pos(rc32, 4); move32();
+ }
+
+ /* Final Prediction Error */
+ IF (pred_err != NULL)
+ {
+ err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32)));
+ *pred_err = L_shr(err, shift);
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
+void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N)
+{
+ Word32 lpc_tmp[MAXLAG + 1];
+ Word32 rc32, tmp0, tmp1;
+ Word16 inv;
+ Counter n, m;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("lpc2rc", sizeof(struct {
+ Word32 lpc_tmp[MAXLAG + 1];
+ Word32 rc32, tmp0, tmp1;
+ Word16 inv;
+ Counter n, m;
+ }));
+#endif
+
+ FOR (n = N; n >= 2; n--)
+ {
+ rc32 = L_shl_pos(lpc[n], 4);
+ rc[n - 1] = round_fx(rc32); move16();
+
+ tmp0 = L_sub(MAX_32, L_abs(Mpy_32_32_lc3plus(rc32, rc32)));
+ FOR (m = 1; m < n; m++)
+ {
+ tmp1 = L_sub(lpc[m], Mpy_32_32_lc3plus(lpc[n - m], rc32));
+ inv = div_s(16383, extract_h(tmp0));
+ lpc_tmp[m] = L_shl_pos(Mpy_32_32_lc3plus(tmp1, Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(tmp0, inv)), inv)), 2); move32();
+ }
+
+ basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32));
+ }
+
+ rc[0] = round_fx(L_shl_pos(lpc[1], 4)); move32();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h
new file mode 100644
index 0000000000000000000000000000000000000000..22f25e9ff204310778be60d2104265f807a7d216
--- /dev/null
+++ b/lib_lc3plus/license.h
@@ -0,0 +1,21 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+
+static const char *const LICENSE =
+ "*******************************************************************************\n"
+ "* ETSI TS 103 634 V1.4.5 *\n"
+ "* Low Complexity Communication Codec Plus (LC3plus) *\n"
+ "* Fixed Point Software V%i.%i.%iETSI, " __DATE__ " *\n"
+ "* Copyright licence is solely granted through ETSI Intellectual Property *\n"
+ "* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *\n"
+ "* estoppel or otherwise. *\n"
+ "*******************************************************************************\n"
+ "\n";
diff --git a/lib_lc3plus/ltpf_coder_fx.c b/lib_lc3plus/ltpf_coder_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..212788d735022b1e18938999794ce0d0ce2423c4
--- /dev/null
+++ b/lib_lc3plus/ltpf_coder_fx.c
@@ -0,0 +1,323 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+/*************************************************************************/
+
+
+void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *mem_in_exp, Word16 mem_in[],
+ Word16 mem_in_len, Word16 param[], Word16 *xin, Word16 len, Word16 *mem_normcorr,
+ Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch,
+ Word16 xin_exp, Word16 frame_dms, Word8 *scratchBuffer
+#ifdef CR9_K_REDUCE_NORM_CORR_TH
+ ,Word16 hrmode
+#endif
+)
+{
+ Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch;
+ Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv;
+ Word32 *ac32;
+ Word16 *ac, *currFrame, *predFrame;
+ Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max;
+ Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active;
+ Counter n, m, fr;
+ Word16 tmp, acflen;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("process_ltpf_coder_fx", sizeof(struct {
+ Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch;
+ Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv;
+ Word32 *ac32;
+ Word16 *ac, *currFrame, *predFrame;
+ Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max;
+ Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active;
+ Counter n, m, fr;
+ Word16 tmp, acflen;
+ }));
+#endif
+
+
+
+ ac32 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 17 = 68 bytes; */
+ ac = (Word16 *)scratchAlign(ac32, sizeof(*ac32) * 17); /* Size = 2 * 17 = 34 bytes */
+ currFrame = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * 128 = 256 bytes */
+ predFrame = (Word16 *)scratchAlign(currFrame, sizeof(*currFrame) * LEN_12K8); /* Size = 2 * 128 = 256 bytes */
+ /* Buffers 'overlap' since they are not used at the same time */ /* Total size used = 512 bytes */
+
+ ltpf_active = 0; move16();
+ norm_corr = 0; move16();
+
+ /* Input buffer */
+ x = mem_in + mem_in_len;
+
+ basop_memmove(x, xin, (len + 1) * sizeof(Word16));
+
+ ASSERT(mem_in_len + len + 1 <= LTPF_MEMIN_LEN + LEN_12K8 + 1);
+
+ /* Scaling */
+ scale0 = sub(getScaleFactor16_0(mem_in, mem_in_len), 3);
+ *mem_in_exp = sub(*mem_in_exp, scale0); move16();
+ scale1 = sub(getScaleFactor16_0(x, len + 1), 3);
+ x_exp = sub(xin_exp, scale1);
+ scale2 = sub(*mem_in_exp, x_exp);
+ IF (scale2 > 0)
+ {
+ Scale_sig(x, len + 1, sub(scale1, scale2));
+ Scale_sig(mem_in, mem_in_len, scale0);
+ x_exp = *mem_in_exp; move16();
+ }
+ ELSE
+ {
+ Scale_sig(x, len + 1, scale1);
+ Scale_sig(mem_in, mem_in_len, add(scale0, scale2));
+ *mem_in_exp = x_exp; move16();
+ }
+
+#ifdef CR9_K_REDUCE_NORM_CORR_TH
+ Word32 normCorrTh = 0;
+ if (hrmode) {
+ normCorrTh = 13107;
+ } else {
+ normCorrTh = 19660;
+ }
+#endif
+
+#ifdef CR9_K_REDUCE_NORM_CORR_TH
+ IF (sub(ol_normcorr, normCorrTh) > 0)
+#else
+ IF (sub(ol_normcorr, 19660) > 0)
+#endif
+ {
+ /* Autocorrelation Bounds */
+ min_pitch = sub(ol_pitch, 4);
+ max_pitch = add(ol_pitch, 4);
+ min_pitch = s_max(min_pitch, MIN_PITCH_12K8);
+ max_pitch = s_min(max_pitch, MAX_PITCH_12K8);
+ ac_min_pitch = sub(min_pitch, 4);
+ ac_max_pitch = add(max_pitch, 4);
+ acflen = len; move16();
+ if (sub(frame_dms, 25) == 0)
+ {
+ acflen = shl(len, 1);
+ x = x - len;
+ }
+
+ /* Compute norm */
+ sum1 = L_mac0(1, x[0], x[0]);
+ sum2 = L_mac0(1, x[-ac_min_pitch], x[-ac_min_pitch]);
+ FOR (m = 1; m < acflen; m++)
+ {
+ sum1 = L_mac0(sum1, x[m], x[m]);
+ sum2 = L_mac0(sum2, x[m - ac_min_pitch], x[m - ac_min_pitch]);
+ }
+ scale1 = norm_l(sum1);
+ sum1 = L_shl_pos(sum1, scale1);
+
+ /* Compute Autocorrelation */
+ FOR (n = ac_min_pitch; n <= ac_max_pitch; n++)
+ {
+ sum0 = L_mac0(0L, x[0], x[0 - n]);
+ FOR (m = 1; m < acflen; m++)
+ {
+ sum0 = L_mac0(sum0, x[m], x[m - n]);
+ }
+ if (n > ac_min_pitch)
+ {
+ sum2 = L_msu0(sum2, x[acflen - 1 - (n - 1)], x[acflen - 1 - (n - 1)]);
+ sum2 = L_mac0_sat(sum2, x[-n], x[-n]);
+ }
+ scale2 = norm_l(sum2);
+ L_tmp = L_shl_pos(sum2, scale2);
+ prod = Mpy_32_32_lc3plus(sum1, L_tmp);
+ shift = norm_l(prod);
+ prod = L_shl_pos(prod, shift);
+ prod_exp = sub(62, add(add(scale1, scale2), shift));
+ inv = Isqrt(prod, &prod_exp);
+ scale0 = norm_l(sum0);
+ sum0 = L_shl_pos(sum0, scale0);
+ prod = Mpy_32_32_lc3plus(sum0, inv);
+ prod_exp = add(sub(31, scale0), prod_exp);
+ test();
+ IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0)
+ {
+ ac[n - ac_min_pitch] = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16();
+ }
+ ELSE
+ {
+ ac[n - ac_min_pitch] = 32767; move16();
+ }
+ }
+
+ /* Find maximum */
+ ac_max = ac[min_pitch - ac_min_pitch]; move16();
+ pitch = min_pitch; move16();
+ FOR (n = min_pitch + 1; n <= max_pitch; n++)
+ {
+ tmp = sub_sat(ac[n - ac_min_pitch], ac_max);
+ if (tmp > 0)
+ {
+ pitch = n; move16();
+ }
+ ac_max = s_max(ac_max, ac[n - ac_min_pitch]);
+ }
+ pitch_int = pitch; move16();
+ pitch_fr = 0; move16();
+ pitch_index = add(pitch_int, 283);
+
+ /* If the pitch is low -> estimate a fractional part */
+ IF (sub(pitch, RES2_PITCH_12K8) < 0)
+ {
+ IF (sub(pitch, RES4_PITCH_12K8) < 0)
+ {
+ pitch_res = 1; move16();
+ min_pitch_fr = -3; move16();
+ }
+ ELSE
+ {
+ pitch_res = 2; move16();
+ min_pitch_fr = -2; move16();
+ }
+ if (sub(pitch, min_pitch) == 0)
+ {
+ min_pitch_fr = 0;
+ }
+ cor_max32 = MIN_32;
+ FOR (fr = min_pitch_fr; fr < 4; fr += pitch_res)
+ {
+ sum0 = L_mult0(ac[pitch_int - ac_min_pitch - 4], ltpf_ac_interp_filt[fr + 3][0]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 3], ltpf_ac_interp_filt[fr + 3][1]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 2], ltpf_ac_interp_filt[fr + 3][2]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 1], ltpf_ac_interp_filt[fr + 3][3]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 0], ltpf_ac_interp_filt[fr + 3][4]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 1], ltpf_ac_interp_filt[fr + 3][5]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 2], ltpf_ac_interp_filt[fr + 3][6]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 3], ltpf_ac_interp_filt[fr + 3][7]);
+ sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 4], ltpf_ac_interp_filt[fr + 3][8]);
+
+ L_tmp = L_sub_sat(sum0, cor_max32);
+ if (L_tmp > 0)
+ {
+ pitch_fr = fr; move16();
+ }
+ cor_max32 = L_max(cor_max32, sum0);
+ }
+ IF (pitch_fr < 0)
+ {
+ pitch_int = sub(pitch_int, 1);
+ pitch_fr = add(pitch_fr, 4);
+ }
+ IF (sub(pitch_int, 127) >= 0)
+ {
+ pitch_index = add(add(shl_pos(pitch_int, 1), shr_pos(pitch_fr, 1)), 126);
+ }
+ ELSE
+ {
+ pitch_index = sub(add(shl_pos(pitch_int, 2), pitch_fr), 128);
+ }
+ }
+ ltpf_pitch = add(shl_pos(pitch_int, 2), pitch_fr);
+
+ /* Filter current and predicted frame */
+
+ FOR (n = 0; n < acflen; n++)
+ {
+ sum0 = L_mult(x[n + 1], inter_filter[0][0][0]);
+ sum0 = L_mac(sum0, x[n], inter_filter[0][0][1]);
+ currFrame[n] = mac_r(sum0, x[n - 1], inter_filter[0][0][2]);
+
+ sum0 = L_mult(x[n - pitch_int + 1], inter_filter[0][pitch_fr][0]);
+ sum0 = L_mac(sum0, x[n - pitch_int], inter_filter[0][pitch_fr][1]);
+ sum0 = L_mac(sum0, x[n - pitch_int - 1], inter_filter[0][pitch_fr][2]);
+ predFrame[n] = mac_r(sum0, x[n - pitch_int - 2], inter_filter[0][pitch_fr][3]);
+ }
+
+ /* Normalized Correlation */
+ sum0 = L_mult0(currFrame[0], predFrame[0]);
+ sum1 = L_mac0(1, predFrame[0], predFrame[0]);
+ sum2 = L_mac0(1, currFrame[0], currFrame[0]);
+ for (m = 1; m < acflen; m++)
+ {
+ sum0 = L_mac0(sum0, currFrame[m], predFrame[m]);
+ sum1 = L_mac0(sum1, predFrame[m], predFrame[m]);
+ sum2 = L_mac0(sum2, currFrame[m], currFrame[m]);
+ }
+
+ scale1 = norm_l(sum1);
+ scale2 = norm_l(sum2);
+ sum1 = L_shl_pos(sum1, scale1);
+ sum2 = L_shl_pos(sum2, scale2);
+ prod = Mpy_32_32_lc3plus(sum1, sum2);
+ shift = norm_l(prod);
+ prod = L_shl_pos(prod, shift);
+ prod_exp = sub(62, add(add(scale1, scale2), shift));
+ inv = Isqrt(prod, &prod_exp);
+ scale0 = norm_l(sum0);
+ sum0 = L_shl_pos(sum0, scale0);
+ prod = Mpy_32_32_lc3plus(sum0, inv);
+ prod_exp = add(sub(31, scale0), prod_exp);
+ test();
+ IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0)
+ {
+ norm_corr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16();
+ }
+ ELSE
+ {
+ norm_corr = 32767; move16();
+ }
+ if (norm_corr < 0)
+ {
+ norm_corr = 0;
+ }
+
+ IF (sub(ltpf_enable, 1) == 0)
+ {
+ test(); test(); test(); test();
+ /* Decision if lptf active */
+ IF ((*mem_ltpf_on == 0 && sub(*mem_normcorr, 30802) > 0 && sub(norm_corr, 30802) > 0 &&
+ (sub(frame_dms, 100) == 0 || sub(*mem_mem_normcorr, 30802) > 0)) ||
+ (sub(*mem_ltpf_on, 1) == 0 && sub(norm_corr, 29491) > 0) ||
+ (sub(*mem_ltpf_on, 1) == 0 && sub(abs_s(sub(ltpf_pitch, *mem_ltpf_pitch)), 8) < 0 &&
+ add(sub(norm_corr, *mem_normcorr), 3277) > 0 && sub(norm_corr, 27525) > 0))
+ {
+ ltpf_active = 1; move16();
+ }
+ }
+
+ param[0] = 1; move16();
+ param[1] = ltpf_active; move16();
+ param[2] = pitch_index; move16();
+ *bits = 11; move16();
+ }
+ ELSE
+ {
+ norm_corr = ol_normcorr; move16();
+ param[0] = 0; move16();
+ param[1] = 0; move16();
+ param[2] = 0; move16();
+ *bits = 1; move16();
+ ltpf_pitch = 0; move16();
+ }
+
+/* Update memory */
+ FOR (n = 0; n < mem_in_len; n++)
+ {
+ mem_in[n] = mem_in[n + len]; move16();
+ }
+
+ *mem_mem_normcorr = *mem_normcorr; move16();
+ *mem_normcorr = norm_corr; move16();
+ *mem_ltpf_on = ltpf_active; move16();
+ *mem_ltpf_pitch = ltpf_pitch; move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/ltpf_decoder_fx.c b/lib_lc3plus/ltpf_decoder_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..3bc82085ef6436548bc71bc769c8da9748ad5eb5
--- /dev/null
+++ b/lib_lc3plus/ltpf_decoder_fx.c
@@ -0,0 +1,394 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr,
+ Word16 gain, Word16 scale_fac_idx, Word16 fs_idx,
+ Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */);
+
+/*************************************************************************/
+
+
+void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len,
+ Word16 *old_e, Word16 *x_in, Word16 *old_x, Word16 *y_out, Word16 *old_y, Word16 ltpf,
+ Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr,
+ Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi,
+ Word16 concealMethod,
+ Word16 damping, Word16 *old_scale_fac_idx,
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms,
+#endif
+ Word8 *scratchBuffer)
+{
+ Counter i;
+ Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34;
+ Word16 *x, *y;
+ Word16 *z;
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ Word32 tmp32, pitch_delta;
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("process_ltpf_decoder_fx", sizeof(struct {
+ Counter i;
+ Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34;
+ Word16 *x, *y;
+ Word16 *z;
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ Word32 tmp32, pitch_delta;
+#endif
+ }));
+#endif
+
+ z = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = MAX_LEN / 4 + 10 */
+
+
+ test();
+ IF ((sub(bfi, 1) == 0) && (sub(concealMethod, LC3_CON_TEC_NS_STD) == 0))
+ {
+ ltpf = 0; move16();
+ ltpf_active = 0; move16();
+ pitch_int = 0; move16();
+ pitch_fr = 0; move16();
+ gain = 0; move16();
+ }
+
+ /* Filter parameters */
+ IF (sub(bfi, 1) != 0)
+ {
+ IF (ltpf == 0)
+ {
+ pitch_int = 0; move16();
+ pitch_fr = 0; move16();
+ }
+ ELSE
+ {
+ /* Decode pitch */
+ IF (sub(pitch_index, 380) < 0)
+ {
+ pitch_int = shr_pos(add(pitch_index, 64), 2);
+ pitch_fr = add(sub(pitch_index, shl_pos(pitch_int, 2)), 128);
+ }
+ ELSE IF (sub(pitch_index, 440) < 0)
+ {
+ pitch_int = shr_pos(sub(pitch_index, 126), 1);
+ pitch_fr = sub(sub(shl_pos(pitch_index, 1), shl_pos(pitch_int, 2)), 252);
+ }
+ ELSE
+ {
+ pitch_int = sub(pitch_index, 283);
+ pitch_fr = 0; move16();
+ }
+ pitch = add(shl_pos(pitch_int, 2), pitch_fr);
+#ifdef ENABLE_HR_MODE
+ IF (sub(fs_idx, 5) == 0)
+ {
+ pitch = round_fx(L_shl_pos(L_mult(shl_pos(pitch, 2), pitch_scale[4]), 1));
+ }
+ ELSE
+#endif
+ {
+ pitch = mult_r(shl_pos(pitch, 2), pitch_scale[fs_idx]);
+ }
+ pitch_int = shr_pos(pitch, 2);
+ pitch_fr = sub(pitch, shl_pos(pitch_int, 2));
+ }
+
+ /* Decode gain */
+ if (scale_fac_idx < 0)
+ {
+ ltpf_active = 0;
+ ASSERT(!(*old_scale_fac_idx < 0 && *mem_ltpf_active == 1));
+ }
+ IF (ltpf_active == 0)
+ {
+ gain = 0; move16();
+ }
+ ELSE
+ {
+ ASSERT(scale_fac_idx >= 0);
+ gain = gain_scale_fac[scale_fac_idx]; move16();
+ }
+ }
+ ELSE IF (sub(concealMethod, LC3_CON_TEC_NS_STD) != 0)
+ {
+ /* fix to avoid not initialized filtering for concelament
+ might be necessary in case of bit errors or rate switching */
+ if (scale_fac_idx < 0) {
+ if (*mem_ltpf_active && *old_scale_fac_idx>=0)
+ {
+ scale_fac_idx = *old_scale_fac_idx;
+ }
+ }
+
+ ltpf_active = *mem_ltpf_active; move16();
+
+ if ((sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0))
+ { /* always start fade off to save filtering WMOPS for the remaining 7.5 ms */
+ assert(bfi == 1);
+ ltpf_active = 0; move16(); /*always start fade off , still maintain *mem_ltpf_active */
+ }
+
+ pitch_int = *old_pitch_int;
+ pitch_fr = *old_pitch_fr;
+ gain = mult_r(*old_gain, damping);
+ }
+
+ test(); test();
+ IF (ltpf_active == 0 && *mem_ltpf_active == 0)
+ {
+ /* LTPF inactive */
+
+ basop_memmove(y_out, x_in, L_frame * sizeof(Word16));
+
+ /* Update */
+ s = sub(*old_e, *x_e);
+ IF (s > 0)
+ {
+ basop_memmove(old_y, &old_y[L_frame], (old_y_len - L_frame) * sizeof(Word16));
+
+ IF (sub(s, 15) > 0)
+ {
+ basop_memset(&old_y[old_y_len - L_frame], 0, (L_frame) * sizeof(Word16));
+
+ basop_memset(old_x, 0, (old_x_len) * sizeof(Word16));
+ }
+ ELSE
+ {
+ FOR (i = 0; i < L_frame; i++)
+ {
+ old_y[i + old_y_len - L_frame] = shr(x_in[i], s); move16();
+ }
+ FOR (i = 0; i < old_x_len; i++)
+ {
+ old_x[i] = shr(x_in[i + L_frame - old_x_len], s); move16();
+ }
+ }
+ }
+ ELSE
+ {
+ IF (sub(s, -15) < 0)
+ {
+ basop_memset(old_y, 0, (old_y_len - L_frame) * sizeof(Word16));
+ }
+ ELSE
+ {
+ FOR (i = 0; i < old_y_len - L_frame; i++)
+ {
+ old_y[i] = shl(old_y[i + L_frame], s); move16();
+ }
+ }
+
+ basop_memmove(&old_y[old_y_len - L_frame], x_in, (L_frame) * sizeof(Word16));
+
+ basop_memmove(old_x, &x_in[L_frame - old_x_len], (old_x_len) * sizeof(Word16));
+
+ *old_e = *x_e; move16();
+ }
+
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ if (bfi == 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){
+ pitch_delta = abs_s(add(sub(*old_pitch_int,pitch_int) , shr_pos(sub(*old_pitch_fr, pitch_fr),2))); //int_old -int_new + (fr_old-fr_new) / 4.0));
+ tmp32 = BASOP_Util_Divide3216_Scale_lc3plus(pitch_delta, MAX(add(*old_pitch_int, shr_pos(*old_pitch_fr,2)), 1),&s0);// = pitch_delta *2^15 / MAX(pitch_fl_c_old, 1);
+ *rel_pitch_change = L_shl_pos(tmp32,s0+16);
+ }
+#endif
+
+ *old_pitch_int = pitch_int; move16();
+ *old_pitch_fr = pitch_fr; move16();
+ *old_gain = 0; move16();
+ *mem_ltpf_active = 0; move16();
+ }
+ ELSE
+ {
+ /* Input/Output buffers */
+ x = old_x + old_x_len;
+ y = old_y + old_y_len;
+
+#ifdef ENABLE_HR_MODE
+ assert(fs_idx < 5 && "Ltpf not supported for 96kHz!\n");
+#endif
+
+ N4 = ltpf_overlap_len[fs_idx]; move16();
+ N34 = sub(L_frame, N4); move16();
+
+ /* Input */
+ basop_memmove(x, x_in, (L_frame) * sizeof(Word16));
+
+ /* Scaling */
+ s0 = sub(s_min(getScaleFactor16_0(old_x, old_x_len), getScaleFactor16_0(old_y, old_y_len)), 1);
+ *old_e = sub(*old_e, s0); move16();
+ s1 = sub(getScaleFactor16(x, L_frame), 1);
+ *x_e = sub(*x_e, s1); move16();
+ s = sub(*old_e, *x_e);
+ IF (s > 0)
+ {
+ Scale_sig(x, L_frame, sub(s1, s));
+ Scale_sig(old_x, old_x_len, s0);
+ Scale_sig(old_y, old_y_len, s0);
+ *x_e = *old_e; move16();
+ }
+ ELSE
+ {
+ Scale_sig(x, L_frame, s1);
+ Scale_sig(old_x, old_x_len, add(s0, s));
+ Scale_sig(old_y, old_y_len, add(s0, s));
+ *old_e = *x_e; move16();
+ }
+
+ /* Filtering */
+ IF (ltpf_active == 0)
+ {
+ ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx,
+ -1);
+ }
+ ELSE IF (*mem_ltpf_active == 0)
+ {
+ ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 1);
+ }
+ ELSE IF (sub(pitch_int, *old_pitch_int) == 0 && sub(*old_pitch_fr, pitch_fr) == 0)
+ {
+ ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 0);
+ }
+ ELSE
+ {
+ ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx,
+ -1);
+ basop_memmove(z, y - tilt_filter_len[fs_idx], (N4 + tilt_filter_len[fs_idx]) * sizeof(Word16));
+ ltpf_synth_filter(y, z + tilt_filter_len[fs_idx], N4, pitch_int, pitch_fr, gain, scale_fac_idx,
+ fs_idx, 1);
+ }
+ IF (ltpf_active > 0)
+ {
+ ltpf_synth_filter(y + N4, x + N4, N34, pitch_int, pitch_fr, gain,
+ scale_fac_idx, fs_idx, 0);
+ }
+ ELSE
+ {
+ basop_memmove(&y[N4], &x[N4], N34 * sizeof(Word16));
+ }
+
+ /* Output */
+ basop_memmove(y_out, y, (L_frame) * sizeof(Word16));
+
+ /* Update */
+ basop_memmove(old_x, &old_x[L_frame], (old_x_len) * sizeof(Word16));
+
+ basop_memmove(old_y, &old_y[L_frame], (old_y_len) * sizeof(Word16));
+
+ *old_pitch_int = pitch_int; move16();
+ *old_pitch_fr = pitch_fr; move16();
+ *old_gain = gain; move16();
+ *mem_ltpf_active = ltpf_active; move16();
+ }
+
+ *old_scale_fac_idx = scale_fac_idx; move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
+static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr,
+ Word16 gain, Word16 scale_fac_idx, Word16 fs_idx,
+ Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */)
+{
+ Word16 *x0;
+ Word16 *y0;
+ Word32 s;
+ Word16 alpha, step;
+ Word16 i, k;
+ Counter j, l;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("ltpf_synth_filter", sizeof(struct {
+ Word16 *x0;
+ Word16 *y0;
+ Word32 s;
+ Word16 alpha, step;
+ Word16 i, k;
+ Counter j, l;
+ }));
+#endif
+
+ ASSERT(scale_fac_idx >= 0);
+
+ step = 0; /* initialize just to avoid compiler warning */
+ alpha = 0; /* initialize just to avoid compiler warning */
+ x0 = &synth_ltp[-pitch_int + inter_filter_shift[fs_idx]];
+ y0 = synth;
+
+ alpha = 0; move16();
+ IF (fade != 0)
+ {
+ if (fade < 0)
+ {
+ alpha = 0x7FFF; move16();
+ }
+
+/* step = 1.f/(float)(length); */
+ if (sub(length, 20) == 0)
+ {
+ step = 1638 /*1.f/20.f Q15*/; move16();
+ }
+ if (sub(length, 40) == 0)
+ {
+ step = 819 /*1.f/40.f Q15*/; move16();
+ }
+ if (sub(length, 60) == 0)
+ {
+ step = 546 /*1.f/60.f Q15*/; move16();
+ }
+ if (sub(length, 80) == 0)
+ {
+ step = 409 /*1.f/80.f Q15*/; move16();
+ }
+ if (sub(length, 120) == 0)
+ {
+ step = 273 /*1.f/120.f Q15*/; move16();
+ }
+
+ if (fade < 0)
+ step = negate(step);
+ }
+
+ FOR (j = 0; j < length; j++)
+ {
+ s = L_mult(x0[0], inter_filter[fs_idx][pitch_fr][0]);
+ FOR (l = 1; l < inter_filter_len[fs_idx]; l++)
+ {
+ s = L_mac(s, x0[-l], inter_filter[fs_idx][pitch_fr][l]);
+ }
+ FOR (l = 0; l < tilt_filter_len[fs_idx]; l++)
+ {
+ s = L_msu(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]);
+ }
+
+ i = msu_r(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]);
+
+ k = mult_r(gain, i);
+
+ if (fade != 0)
+ k = mult_r(k, alpha);
+
+ synth_ltp[j] = add(synth[j], k); move16();
+
+ if (fade != 0)
+ alpha = add(alpha, step);
+
+ x0++;
+ y0++;
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/makefile b/lib_lc3plus/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d86232d67a1887e421f561810dab7e78d2436437
--- /dev/null
+++ b/lib_lc3plus/makefile
@@ -0,0 +1,180 @@
+#******************************************************************************
+# ETSI TS 103 634 V1.4.5 *
+# Low Complexity Communication Codec Plus (LC3plus) *
+# *
+# Copyright licence is solely granted through ETSI Intellectual Property *
+# Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+# estoppel or otherwise. *
+#*****************************************************************************/
+
+# Options
+AFL = 0
+GCOV = 0
+NO_POST_REL_CHANGES_TEST = 0
+OPTIM = 0
+SUBSET = ALL
+WMOPS = 1
+HR = 1
+CLANG = 0
+SHORT_PLC_FADEOUT = 0
+
+# Paths
+VPATH = . basic_op
+BUILD = build
+CC = gcc
+LINK = $(CC)
+
+# Binary Name
+NAME_LC3 = LC3plus
+# Shared Library Name
+LIB_LC3 = libLC3plus.so
+
+# Default tool settings
+RM = rm -f
+
+ifndef VERBOSE
+QUIET_CC = @echo ' ' Compiling $<;
+QUIET_LINK= @echo ' ' Linking $@;
+QUIET = @
+endif
+
+# C compiler flags
+# Preprocessor(-I/-D) / Compiler / Linker flags
+CPPFLAGS += -Ibasic_op -DSUBSET_$(SUBSET)
+CFLAGS += -std=c99 -fPIC \
+ -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \
+ -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \
+ -Werror-implicit-function-declaration
+
+ifneq "$(DEBUG)" "0"
+CFLAGS += -g3
+LDFLAGS += -g3
+endif
+
+ifeq "$(HR)" "0"
+CFLAGS += -DDISABLE_HR_MODE
+endif
+
+ifeq "$(SHORT_PLC_FADEOUT)" "1"
+CFLAGS += -DPLC_TUNING_SHORT_FADEOUT
+endif
+
+# memory sanitizer, find use of uninitialized memory
+ifeq "$(CLANG)" "1"
+ CC = clang
+ CFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
+ LDFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
+ OPTIM = 2
+endif
+
+# address sanitizer, find buffer overflows
+ifeq "$(CLANG)" "2"
+ CC = clang
+ CFLAGS += -fsanitize=address -fno-omit-frame-pointer
+ LDFLAGS += -fsanitize=address -fno-omit-frame-pointer
+ OPTIM = 2
+endif
+
+# undefined behavior sanitizer, find bugs like integer overflows
+ifeq "$(CLANG)" "3"
+ CC = clang
+ CFLAGS += -fsanitize=undefined
+ LDFLAGS += -fsanitize=undefined
+ OPTIM = 2
+endif
+
+LDFLAGS += -lm
+
+DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD)/$*.Td
+
+ifeq "$(GCOV)" "1"
+CFLAGS += -fprofile-arcs -ftest-coverage
+LDFLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+OPTIM ?= 0
+CFLAGS += -O$(OPTIM)
+
+CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR))
+
+ifeq "$(NO_POST_REL_CHANGES_TEST)" "1"
+CFLAGS += -DNO_POST_REL_CHANGES
+endif
+
+# disable wmops instrumentation
+ifeq "$(WMOPS)" "0"
+ CPPFLAGS += -DWMOPS=0 -DDONT_COUNT_MEM
+endif
+
+# dependency magic
+CC_FLAGS = '$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)'
+POSTCOMPILE = mv -f $(BUILD)/$*.Td $(BUILD)/$*.d && touch $@
+
+###############################################################################
+
+SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c)))
+
+EXCL := ccConvert.c
+SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c)))
+SRCS := $(filter-out $(EXCL), $(SRCS))
+
+EXCL_CCC := $(BUILD)/codec_exe.o
+OBJS_CCC_UNF := $(addprefix $(BUILD)/, $(SRCS:.c=.o))
+OBJS_CCC := $(filter-out $(EXCL_CCC), $(OBJS_CCC_UNF))
+
+OBJS := $(addprefix $(BUILD)/, $(SRCS:.c=.o))
+
+LIBSRCS := $(filter-out $(DIR)/ccConvert.c $(DIR)/codec_exe.c, $(SRCS))
+LIBOBJS := $(addprefix $(BUILD)/, $(LIBSRCS:.c=.o))
+
+###############################################################################
+
+.PHONY: all clean help force
+
+all: $(NAME_LC3)
+
+help:
+ @echo 'Targets:'
+ @echo ' $(NAME_LC3) (default)'
+ @echo ' $(LIB_LC3)'
+ @echo ' ccConvert'
+ @echo 'Syntax: make [OPTION=VALUE ...]'
+ @echo 'Build options:'
+ @echo ' NO_POST_REL_CHANGES_TEST $(NO_POST_REL_CHANGES_TEST) [0,1]'
+ @echo ' OPTIM $(OPTIM) [0-3]'
+ @echo ' SUBSET $(SUBSET) [NB,WB,SSWB,SWB,FB,UB,ALL]'
+ @echo ' WMOPS $(WMOPS) [0,1]'
+ @echo ' SHORT_PLC_FADEOUT $(SHORT_PLC_FADEOUT) [0,1]'
+ @echo 'Debug options:'
+ @echo ' AFL $(AFL) [0,1]'
+ @echo ' CLANG $(CLANG) [0-3]'
+ @echo ' GCOV $(GCOV) [0,1]'
+
+$(NAME_LC3): $(OBJS)
+ @echo 'Linking' $@
+ $(QUIET) $(LINK) $(OBJS) -o $@ $(LDFLAGS)
+
+$(LIB_LC3): $(LIBOBJS)
+ @echo 'Linking' $@
+ $(QUIET) $(LINK) --shared $(OBJS) -o $@ $(LDFLAGS)
+
+ccConvert: $(BUILD)/ccConvert.o $(OBJS_CCC)
+ @echo 'Linking' $@
+ $(QUIET) $(LINK) $? -o $@ $(LDFLAGS)
+
+clean:
+ $(QUIET) rm -rf $(NAME_LC3) $(LIB_LC3) $(BUILD) ccConvert
+
+$(BUILD)/%.o : %.c $(BUILD)/cc_flags
+ @echo 'Compiling' $<
+ $(QUIET) $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+ $(QUIET) $(POSTCOMPILE)
+
+# force rebuild if compilation flags changed
+$(BUILD)/cc_flags: force
+ $(QUIET) mkdir -p $(BUILD)
+ $(QUIET) echo $(CC_FLAGS) | cmp -s - $@ || echo $(CC_FLAGS) > $@
+
+# force rebuild if include dependency changed
+$(BUILD)/%.d: ;
+include $(wildcard $(patsubst %, $(BUILD)/%.d, $(basename $(SRCS))))
diff --git a/lib_lc3plus/mdct_fx.c b/lib_lc3plus/mdct_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e9157204f6addd73df699cc858668a778ef8e0f
--- /dev/null
+++ b/lib_lc3plus/mdct_fx.c
@@ -0,0 +1,223 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+/* Union holding buffers to conserve stack memory. */
+
+void processMdct_fx(
+#ifdef ENABLE_HR_MODE
+ Word32 x[], /* i: time input signal */
+#else
+ Word16 x[], /* i: time input signal */
+#endif
+ Word16 x_exp, Word16 N, /* i: block size N */
+#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+# ifdef ENABLE_HR_MODE
+ Word16 hrmode, /* i: indicate high precision */
+# endif
+#endif
+#ifdef ENABLE_HR_MODE
+ const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#else
+ const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+#endif
+ Word16 wLen, /* i: window length */
+#ifdef ENABLE_HR_MODE
+ Word32 mem[], /* i/o: last block of input samples */
+#else
+ Word16 mem[], /* i/o: last block of input samples */
+#endif
+ Word16 memLen, /* i: length of last sample block */
+ Word32 y[], /* o: spectral data */
+ Word16 * y_e, /* o: spectal data exponent */
+ Word8 * scratchBuffer)
+{
+ Counter i;
+ Word16 z, s, m;
+#ifdef ENABLE_HR_MODE
+ Word32 *buf;
+#else
+ Word16 *buf;
+#endif
+ Word32 *workBuffer;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processMdct_fx", sizeof(struct {
+ Counter i;
+ Word16 z, s, m;
+ Word16 *buf;
+ Word32 *workBuffer;
+ }));
+#endif
+
+ /* Buffers overlap since they are not used at the same time */
+#ifdef ENABLE_HR_MODE
+ buf = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */
+#else
+ buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */
+#endif
+ workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN */
+
+ /* Init (constant per sample rate) */
+ z = (N << 1) - wLen; /* number of leading zeros in window */
+ m = N >> 1; /* half block size */
+
+#ifdef ENABLE_HR_MODE
+ basop_memmove(buf, mem, memLen * sizeof(Word32));
+
+ basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word32));
+
+ basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word32));
+#else
+ basop_memmove(buf, mem, memLen * sizeof(Word16));
+
+ basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word16));
+
+ basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word16));
+#endif
+
+#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+
+# ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ FOR (i = 0; i < m; i++)
+ {
+ y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32();
+ }
+
+ FOR (i = 0; i < z; i++)
+ {
+ y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32();
+ }
+
+ FOR (i = i; i < m; i++)
+ {
+ y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32();
+ }
+ } else {
+# ifdef CR9_B_FIX_MDCT_OVERFLOW
+ FOR (i = 0; i < m; i++)
+ {
+ y[m + i] = L_msu0(L_mult0(round_fx_sat(buf[i]), round_fx(w[i])), round_fx_sat(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32();
+ }
+
+ FOR (i = 0; i < z; i++)
+ {
+ y[m - 1 - i] = L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32();
+ }
+
+ FOR (i = i; i < m; i++)
+ {
+ y[m - 1 - i] = L_mac0(L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx_sat(x[4 * m - memLen - 1 - i]),
+ round_fx(w[4 * m - 1 - i])); move32();
+ }
+# else /* CR9_B_FIX_MDCT_OVERFLOW */
+ FOR (i = 0; i < m; i++)
+ {
+ y[m + i] = L_msu0(L_mult0(round_fx(buf[i]), round_fx(w[i])), round_fx(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32();
+ }
+
+ FOR (i = 0; i < z; i++)
+ {
+ y[m - 1 - i] = L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32();
+ }
+
+ FOR (i = i; i < m; i++)
+ {
+ y[m - 1 - i] = L_mac0(L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx(x[4 * m - memLen - 1 - i]),
+ round_fx(w[4 * m - 1 - i])); move32();
+ }
+# endif /* CR9_B_FIX_MDCT_OVERFLOW */
+ }
+# else
+ /* regular resolution only */
+ FOR (i = 0; i < m; i++)
+ {
+ y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32();
+ }
+
+ FOR (i = 0; i < z; i++)
+ {
+ y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32();
+ }
+
+ FOR (i = i; i < m; i++)
+ {
+ y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i],
+ w[4 * m - 1 - i]); move32();
+ }
+# endif
+
+#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+ FOR (i = 0; i < m; i++)
+ {
+# ifdef ENABLE_HR_MODE
+ y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32();
+# else
+ y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32();
+# endif
+ }
+
+ FOR (i = 0; i < z; i++)
+ {
+# ifdef ENABLE_HR_MODE
+ y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32();
+# else
+ y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32();
+# endif
+ }
+
+ FOR (i = i; i < m; i++)
+ {
+# ifdef ENABLE_HR_MODE
+ y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32();
+# else
+ y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i],
+ w[4 * m - 1 - i]); move32();
+# endif
+ }
+
+#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */
+
+ s = s_max(0, getScaleFactor32_lc3plus(y, N));
+ FOR (i = 0; i < N; i++)
+ {
+ y[i] = L_shl(y[i], s); move32();
+ }
+
+ *y_e = sub(sub(x_exp, 2), s);
+
+ /* N=20 only for 2.5ms possible */
+ /* maybe implement this a pre init of shift */
+ if (sub(N, 20) <= 0)
+ {
+ *y_e = add(*y_e, 2);
+ }
+ else if (sub(N, 120) <= 0)
+ {
+ *y_e = add(*y_e, 1);
+ }
+#ifdef ENABLE_HR_MODE
+ dct_IV(y, y_e, N,
+# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION
+ hrmode,
+# endif
+ workBuffer);
+#else
+ dct_IV(y, y_e, N, workBuffer);
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/mdct_shaping_fx.c b/lib_lc3plus/mdct_shaping_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b36265fd4132cf28c7967e31b63e30b188408dc
--- /dev/null
+++ b/lib_lc3plus/mdct_shaping_fx.c
@@ -0,0 +1,74 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processMdctShaping_fx(Word32 x[],
+#ifdef ENABLE_HR_MODE
+ Word32 scf[],
+#else
+ Word16 scf[],
+#endif
+ Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts)
+{
+ Counter i, j;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processMdctShaping_fx", sizeof(struct { Counter i, j; }));
+#endif
+
+ j = 0; move16();
+ FOR (i = 0; i < fdns_npts; i++)
+ {
+ FOR (; j < bands_offset[i + 1]; j++)
+ {
+#ifdef ENABLE_HR_MODE
+ x[j] = L_shl(Mpy_32_32_lc3plus(x[j], scf[i]), scf_exp[i]); move32();
+#else
+ x[j] = L_shl(Mpy_32_16_lc3plus(x[j], scf[i]), scf_exp[i]); move32();
+#endif
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
+void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e)
+{
+ Counter i;
+ Word16 scf_exp_max;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processLpcGainScaling", sizeof(struct {
+ Counter i;
+ Word16 scf_exp_max;
+ }));
+#endif
+
+ scf_exp_max = scf_exp[0]; move16();
+
+ FOR (i = 1; i < fdns_npts; i++)
+ {
+ scf_exp_max = s_max(scf_exp_max, scf_exp[i]);
+ }
+
+ FOR (i = 0; i < fdns_npts; i++)
+ {
+ scf_exp[i] = sub(scf_exp[i], scf_exp_max); move16();
+ }
+
+ *x_e = add(*x_e, scf_exp_max); move16();
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/near_nyquist_detector_fx.c b/lib_lc3plus/near_nyquist_detector_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..8ae29cbb84a72388e35216449857c0f300bea57b
--- /dev/null
+++ b/lib_lc3plus/near_nyquist_detector_fx.c
@@ -0,0 +1,141 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index,
+ const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp
+#ifdef CR8_E_TONE_DETECTOR
+#ifdef ENABLE_HR_MODE
+ ,Word16 frame_dms, Word16 hrmode)
+#else
+ )
+#endif
+#else
+ )
+#endif
+{
+ *near_nyquist_flag = 0;
+#ifdef CR8_E_TONE_DETECTOR
+#ifdef ENABLE_HR_MODE
+ IF (hrmode == 0){
+#endif
+#endif
+ IF (sub(fs_idx, 4) < 0)
+ {
+ Dyn_Mem_Deluxe_In(
+ Word16 i;
+ Word16 nrg_above_thresh;
+ Word16 ener_low_exp;
+ Word16 ener_high_exp;
+ Word16 comp_energy_exp;
+ Word32 comp_energy;
+ Word32 ener_low;
+ Word32 ener_high;
+ );
+
+ ener_low = 0; move32();
+ ener_low_exp = 0; move16();
+ FOR (i = 0; i < near_nyquist_index; i++)
+ {
+ ener_low = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_low, ener_low_exp, &ener_low_exp);
+ }
+
+ ener_high = 0; move32();
+ ener_high_exp = 0; move16();
+ FOR (i = near_nyquist_index; i < bands_number; i++)
+ {
+ ener_high = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_high, ener_high_exp, &ener_high_exp);
+ }
+
+ comp_energy = Mpy_32_16_lc3plus(ener_low, NN_thresh); /* Mpy_32_16_lc3plus -> 32Q15 */
+ comp_energy_exp = add(add(ener_low_exp, NN_thresh_exp),15);
+
+ nrg_above_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(ener_high, ener_high_exp, comp_energy, comp_energy_exp); /* 1 if firstNumber > secondNumber */
+
+ if (sub(nrg_above_thresh, 1) == 0)
+ {
+ *near_nyquist_flag = 1;
+ }
+
+ Dyn_Mem_Deluxe_Out();
+ }
+#ifdef CR8_E_TONE_DETECTOR
+#ifdef ENABLE_HR_MODE
+ }
+ ELSE // hrmode == 1
+ {
+ // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy)));
+ Word32 td_thresh;
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ td_thresh = TD_HR_thresh_2_5ms;
+ BREAK;
+ case 50:
+ td_thresh = TD_HR_thresh_5ms;
+ BREAK;
+ #ifdef ENABLE_075_DMS_MODE
+ case 75:
+ td_thresh = TD_HR_thresh_7_5ms;
+ BREAK;
+ #endif
+ default: /* 100 */
+ td_thresh = TD_HR_thresh_10ms;
+ BREAK;
+ }
+
+ Word16 mean_ener_exp = 0;
+
+ Word32 sum_ener = 0; move32();
+ Word16 sum_ener_exp = 0; move16();
+ FOR (Word16 i = 0; i < bands_number; i++)
+ {
+ sum_ener = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, sum_ener, sum_ener_exp, &sum_ener_exp);
+ }
+
+ Word16 denom = sub(14,norm_s(bands_number));
+ IF (sub(frame_dms, 50) == 0){
+ denom = sub(15,norm_s(bands_number)); move16();
+ }
+
+ Word32 mean_ener = L_shr(sum_ener, denom); move32(); // = sum_ener / bands_number
+ mean_ener_exp = sum_ener_exp; move16();
+
+ Word32 sum_ener_log2 = 0;move32();
+ Word16 sum_ener_log2_exp = 0;move16();
+ Word32 mean_ener_log2 = 0;move32();
+
+ FOR (Word16 i = 0; i < bands_number; i++)
+ {
+ IF (ener_fx[i] != 0) {
+ Word32 log2Value = L_add(BASOP_Util_Log2_lc3plus(ener_fx[i]), L_shl_pos(L_deposit_l(ener_fx_exp), 25));
+ /* input argument is in Q7.25 , returns pow(2,(x/64)
+ floatingpoint value log2_fl = log2Value/pow(2,31-6) */
+ sum_ener_log2 = BASOP_Util_Add_Mant32Exp_lc3plus(log2Value, 6, sum_ener_log2, sum_ener_log2_exp, &sum_ener_log2_exp); move32();
+ }
+ }
+ mean_ener_log2 = L_shr(sum_ener_log2, denom); move32(); //mean_ener_log2 = sum_ener_log2 / bands_number
+ Word16 mean_ener_log2_exp = sum_ener_log2_exp;
+ Word32 mean_ener_log2_fl = L_shr_pos(mean_ener_log2 ,s_min(31, sub(31,mean_ener_log2_exp))); //mean_ener_log2_fl = mean_ener_log2 / 2^(31-mean_ener_log2_exp)
+ Word32 inv_flatness = 0;
+ if (L_sub(norm_l(mean_ener),sub(sub(mean_ener_exp,31),mean_ener_log2_fl)) < 0 ) {
+ inv_flatness = maxWord32;
+ }
+ else {
+ inv_flatness = L_shl(mean_ener, s_max(-31,sub(sub(mean_ener_exp,31),mean_ener_log2_fl)));
+ }
+ IF (L_sub(inv_flatness, td_thresh) > 0) {
+ *near_nyquist_flag = 1; move16();
+ }
+ }
+ #endif // ENABLE_HR_MODE
+#endif // CR8_E_TONE_DETECTOR
+}
diff --git a/lib_lc3plus/noise_factor_fx.c b/lib_lc3plus/noise_factor_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..75ffb5fac3294e2c1dfa5be1a19588f1ddf88c3b
--- /dev/null
+++ b/lib_lc3plus/noise_factor_fx.c
@@ -0,0 +1,252 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+
+void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[],
+# ifdef ENABLE_HR_MODE
+ Word32 xq[],
+# else
+ Word16 xq[],
+# endif
+ Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes,
+ Word8 *scratchBuffer
+# ifdef ENABLE_HR_MODE
+ ,Word16 hrmode
+# endif
+)
+{
+ Dyn_Mem_Deluxe_In(Counter k; Word16 nzeros, s1, s2, s3, c, idx, fac_unq, *ind;
+ Word16 noisefillwidth, noisefillstart, N; Word32 Lsum;);
+
+
+
+ ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */
+
+ noisefillwidth = 0;
+ noisefillstart = 0;
+ c = 0;
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ N = BW_cutoff_bin_all_HR[BW_cutoff_idx];
+ move16();
+ }
+ else
+#endif
+ {
+ N = BW_cutoff_bin_all[BW_cutoff_idx];
+ move16();
+ }
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ N = shr_pos(N, 2);
+ noisefillwidth = NOISEFILLWIDTH_2_5MS;
+ noisefillstart = NOISEFILLSTART_2_5MS;
+ BREAK;
+ case 50:
+ N = shr_pos(N, 1);
+ noisefillwidth = NOISEFILLWIDTH_5MS;
+ noisefillstart = NOISEFILLSTART_5MS;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2)));
+ noisefillwidth = NOISEFILLWIDTH_7_5MS;
+ noisefillstart = NOISEFILLSTART_7_5MS;
+ BREAK;
+# endif
+ case 100:
+ noisefillwidth = NOISEFILLWIDTH;
+ noisefillstart = NOISEFILLSTART;
+ BREAK;
+ }
+
+ nzeros = -2 * noisefillwidth - 1;
+ move16();
+
+ FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++)
+ {
+ if (xq[k] != 0)
+ {
+ nzeros = -2 * noisefillwidth - 1;
+ move16();
+ }
+ if (xq[k] == 0)
+ {
+ nzeros = add(nzeros, 1);
+ }
+ }
+
+ FOR (k = noisefillstart; k < N - noisefillwidth; k++)
+ {
+ if (xq[k + noisefillwidth] != 0)
+ {
+ nzeros = -2 * noisefillwidth - 1;
+ move16();
+ }
+ if (xq[k + noisefillwidth] == 0)
+ {
+ nzeros = add(nzeros, 1);
+ }
+ if (nzeros >= 0)
+ {
+ ind[c++] = k;
+ move16();
+ }
+ }
+
+ FOR (k = N - noisefillwidth; k < N; k++)
+ {
+ nzeros = add(nzeros, 1);
+ if (nzeros >= 0)
+ {
+ ind[c++] = k;
+ move16();
+ }
+ }
+
+ IF (c == 0)
+ {
+ fac_unq = 0;
+ move16();
+ }
+ ELSE
+ {
+
+ IF (target_bytes <= 20 && frame_dms == 100)
+ {
+ Word32 ind_sum;
+ Word16 mean_ind;
+
+ Word16 fac_unq1, fac_unq2;
+
+ /* calculate mean index */
+ ind_sum = ind[0];
+ move32();
+ FOR (k = 1; k < c; k++)
+ {
+ ind_sum = L_add(ind_sum, ind[k]);
+ }
+
+ mean_ind = BASOP_Util_Divide3216_Scale_lc3plus(ind_sum, c, &s2);
+ mean_ind = shl(mean_ind, s2 + 1);
+
+ assert(0 <= mean_ind && mean_ind <= ind[c - 1]);
+
+ /* calculate noise filling gain for low frequencies */
+ s2 = 0; move16();
+ if (sub(mean_ind, ind[0]) > 0)
+ {
+ /* calculate scale to ensure that Lsum does not overflow */
+ s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(mean_ind, ind[0]))), 0);
+ }
+ Lsum = L_shr_pos_pos(L_abs(x[ind[0]]), s2);
+
+ FOR (k = 1; k < c && ind[k] <= mean_ind; k++)
+ {
+ /* scale before adding to Lsum */
+ Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2));
+ }
+ fac_unq1 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, k, &s1);
+ /* add scale applied during summing */
+ s1 = add(s1, s2);
+ fac_unq1 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq1, gg, &s2);
+ s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
+ s2 = norm_s(fac_unq1);
+ test();
+ IF (fac_unq1 != 0 && add(s3, s2) < 0)
+ {
+ fac_unq1 = MAX_16;
+ move16();
+ }
+ ELSE
+ {
+ s3 = s_min(s_max(s3, -15), 15);
+ fac_unq1 = shr_r(fac_unq1, s3);
+ }
+
+ /* calculate noise filling gain for high frequencies */
+ Lsum = 0;
+ move16();
+ idx = sub(c, k);
+ FOR (; k < c; k++)
+ {
+ Lsum = L_add(Lsum, L_abs(x[ind[k]]));
+ }
+ fac_unq2 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, idx, &s1);
+ fac_unq2 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq2, gg, &s2);
+ s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
+ s2 = norm_s(fac_unq1);
+ test();
+ IF (fac_unq2 != 0 && add(s3, s2) < 0)
+ {
+ fac_unq2 = MAX_16;
+ move16();
+ }
+ ELSE
+ {
+ s3 = s_min(s_max(s3, -15), 15);
+ fac_unq2 = shr_r(fac_unq2, s3);
+ }
+
+ /* calculate noise filling gain as minimum over high and low frequencies */
+ fac_unq = s_min(fac_unq1, fac_unq2);
+ }
+ ELSE
+ {
+ /* calculate scale to ensure that Lsum does not overflow */
+ s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(N,ind[0]))), 0);
+ Lsum = L_abs(x[ind[0]]);
+ FOR (k = 1; k < c; k++)
+ {
+ /* scale before adding to Lsum */
+ Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2));
+ }
+ fac_unq = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, c, &s1);
+ /* add scale applied during summing */
+ s1 = add(s1, s2);
+ fac_unq = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq, gg, &s2);
+ s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e))));
+ s2 = norm_s(fac_unq);
+ test();
+ IF (fac_unq != 0 && add(s3, s2) < 0)
+ {
+ fac_unq = MAX_16;
+ move16();
+ }
+ ELSE
+ {
+ fac_unq = shr_r(fac_unq, s_max(s_min(s3, 15), -15));
+ }
+ }
+ }
+
+ idx = round_fx(L_sub(0x80000, L_mult(fac_unq, 16)));
+ if (sub(idx, 7) > 0)
+ {
+ idx = 7;
+ move16();
+ }
+ if (idx < 0)
+ {
+ idx = 0;
+ move16();
+ }
+ *fac_ns_idx = idx;
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/noise_filling_fx.c b/lib_lc3plus/noise_filling_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..9da870553279a9ce8ce82c47a53780270b7d3313
--- /dev/null
+++ b/lib_lc3plus/noise_filling_fx.c
@@ -0,0 +1,149 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+/*************************************************************************/
+
+
+
+void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx,
+ Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter k;
+ Word16 nzeros, fac_ns, *ind, c;
+ Word16 noisefillwidth, noisefillstart, N;
+ Word32 L_tmp, L_tmp_neg, L_tmp_pc, L_tmp_neg_pc;
+ );
+
+ ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */
+
+ c = 0; move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode == 1)
+ {
+ N = BW_cutoff_bin_all_HR[BW_cutoff_idx];
+ move16();
+ }
+ else
+#endif
+ {
+ N = BW_cutoff_bin_all[BW_cutoff_idx];
+ move16();
+ }
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ N = shr_pos(N, 2);
+ noisefillwidth = NOISEFILLWIDTH_2_5MS;
+ noisefillstart = NOISEFILLSTART_2_5MS;
+ BREAK;
+ case 50:
+ N = shr_pos(N, 1);
+ noisefillwidth = NOISEFILLWIDTH_5MS;
+ noisefillstart = NOISEFILLSTART_5MS;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2)));
+ noisefillwidth = NOISEFILLWIDTH_7_5MS;
+ noisefillstart = NOISEFILLSTART_7_5MS;
+ BREAK;
+#endif
+ default: /* 100 */
+ noisefillwidth = NOISEFILLWIDTH;
+ noisefillstart = NOISEFILLSTART;
+ BREAK;
+ }
+
+ nzeros = -2 * noisefillwidth - 1; move16();
+
+ FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++)
+ {
+ if (xq[k] != 0)
+ {
+ nzeros = -2 * noisefillwidth - 1; move16();
+ }
+ if (xq[k] == 0)
+ {
+ nzeros = add(nzeros, 1);
+ }
+ }
+
+ FOR (k = noisefillstart; k < N - noisefillwidth; k++)
+ {
+ if (xq[k + noisefillwidth] != 0)
+ {
+ nzeros = -2 * noisefillwidth - 1; move16();
+ }
+ if (xq[k + noisefillwidth] == 0)
+ {
+ nzeros = add(nzeros, 1);
+ }
+ if (nzeros >= 0)
+ {
+ ind[c++] = k; move16();
+ }
+ }
+
+ FOR (k = N - noisefillwidth; k < N; k++)
+ {
+ nzeros = add(nzeros, 1);
+ if (nzeros >= 0)
+ {
+ ind[c++] = k; move16();
+ }
+ }
+
+ IF (c > 0)
+ {
+ fac_ns = shl_pos(sub(8, fac_ns_idx), 11);
+ L_tmp = L_shr_sat(L_deposit_l(fac_ns), sub(xq_e, 16));
+ L_tmp_neg = L_negate(L_tmp);
+ L_tmp_pc = L_shr_sat(L_deposit_l(fac_ns_pc), sub(xq_e, 16));
+ L_tmp_neg_pc = L_negate(L_tmp_pc);
+
+ FOR (k = 0; k < c; k++)
+ {
+ nfseed = extract_l(L_mac0(13849, nfseed, 31821));
+ IF (nfseed >= 0)
+ {
+ IF (ind[k] < spec_inv_idx)
+ {
+ xq[ind[k]] = L_tmp; move32();
+ }
+ ELSE
+ {
+ xq[ind[k]] = L_tmp_pc; move32();
+ }
+ }
+ IF (nfseed < 0)
+ {
+ IF (ind[k] < spec_inv_idx)
+ {
+ xq[ind[k]] = L_tmp_neg; move32();
+ }
+ ELSE
+ {
+ xq[ind[k]] = L_tmp_neg_pc; move32();
+ }
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/olpa_fx.c b/lib_lc3plus/olpa_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..a72d8b61cf1613fab40b9a00978190ae15a3aba8
--- /dev/null
+++ b/lib_lc3plus/olpa_fx.c
@@ -0,0 +1,289 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+/*************************************************************************/
+
+
+void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8,
+ Word16 len, Word16 *normcorr, Word16 *mem_pitch,
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ Word16 *pitch_flag,
+#endif
+ Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer)
+{
+ Word32 sum, sum0, sum1, sum2, prod, inv;
+ Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch;
+ Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len;
+ Word32 max32;
+ Word32 *ac;
+ Word16 *s6k4;
+ Counter n;
+
+ Counter m;
+ Word32 L_tmp, L_tmp2;
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("process_olpa_fx", sizeof(struct {
+ Word32 sum, sum0, sum1, sum2, prod, inv;
+ Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch;
+ Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len;
+ Word32 max32;
+ Word32 *ac;
+ Word16 *s6k4;
+ Counter n;
+ Word32 sums[3];
+ Counter m;
+ Word32 L_tmp, L_tmp2;
+ }));
+#endif
+
+ /* Buffer alignment */
+ ac = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * RANGE_PITCH_6K4 = 392 bytes */
+
+ /* Downsample input signal by a factor of 2 (12.8kHz -> 6.4kHz) */
+ mem_in_len = MAX_PITCH_6K4; move16();
+ len2 = shr(len, 1);
+ acflen = len2; move16();
+
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ SWITCH(frame_dms)
+ {
+ case 50:
+ mem_in_len = add(mem_in_len, 32);
+ acflen = add(acflen, 32);
+ break;
+
+ case 25:
+ mem_in_len = add(mem_in_len, 48);
+ acflen = add(acflen, 48);
+ break;
+ }
+#endif
+
+#ifndef CR9_F_PITCH_WIN_LEN_FIX
+ IF (sub(frame_dms, 25) == 0)
+ {
+ mem_in_len = add(mem_in_len, 16);
+ acflen = add(acflen, 16);
+ }
+#endif
+
+ s6k4 = mem_s6k4 + mem_in_len;
+ sum = L_mac(L_mac(L_mult(mem_s12k8[0], 4053), mem_s12k8[1], 7712), mem_s12k8[2], 9239);
+ *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[0], 7712), s12k8[1], 4053)); move16();
+ sum = L_mac(L_mac(L_mult(mem_s12k8[2], 4053), s12k8[0], 7712), s12k8[1], 9239);
+ *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[2], 7712), s12k8[3], 4053)); move16();
+
+ FOR (n = 5; n < len; n += 2)
+ {
+ sum = L_mac(L_mac(L_mult(s12k8[n - 4], 4053), s12k8[n - 3], 7712), s12k8[n - 2], 9239);
+ *s6k4++ = round_fx_sat(L_mac_sat(L_mac(sum, s12k8[n - 1], 7712), s12k8[n], 4053)); move16();
+ }
+
+ mem_s12k8[0] = s12k8[len - 3]; move16();
+ mem_s12k8[1] = s12k8[len - 2]; move16();
+ mem_s12k8[2] = s12k8[len - 1]; move16();
+
+ /* Scale downsampled signal */
+ s6k4 = mem_s6k4 + mem_in_len;
+ scale0 = sub(getScaleFactor16_0(mem_s6k4, mem_in_len), 3);
+ *mem_s6k4_exp = sub(*mem_s6k4_exp, scale0); move16();
+ scale1 = sub(getScaleFactor16_0(s6k4, len2), 3);
+ s6k4_exp = sub(s12k8_exp, scale1);
+ scale2 = sub(*mem_s6k4_exp, s6k4_exp);
+ IF (scale2 > 0)
+ {
+ Scale_sig(s6k4, len2, sub(scale1, scale2));
+ shift = scale0; move16();
+ s6k4_exp = *mem_s6k4_exp; move16();
+ }
+ ELSE
+ {
+ Scale_sig(s6k4, len2, scale1);
+ shift = add(scale0, scale2);
+ *mem_s6k4_exp = s6k4_exp; move16();
+ }
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ SWITCH(frame_dms)
+ {
+ case 50:
+ s6k4 = s6k4 - 32;
+ break;
+
+ case 25:
+ s6k4 = s6k4 - 48;
+ break;
+ }
+#endif
+
+#ifndef CR9_F_PITCH_WIN_LEN_FIX
+ if (sub(frame_dms, 25) == 0)
+ {
+ s6k4 = s6k4 - 16;
+ }
+#endif
+ Scale_sig(mem_s6k4, mem_in_len, shift);
+
+ /* Compute autocorrelation */
+ FOR (n = MIN_PITCH_6K4; n <= MAX_PITCH_6K4; n++)
+ {
+ sum = L_mult0(s6k4[0], s6k4[0 - n]);
+ FOR (m = 1; m < acflen; m++)
+ {
+ sum = L_mac0(sum, s6k4[m], s6k4[m - n]);
+ }
+ ac[n - MIN_PITCH_6K4] = sum; move32();
+ }
+
+ /* Weight autocorrelation and find maximum */
+ max32 = Mpy_32_16_lc3plus(ac[0], olpa_ac_weighting[0]); move32();
+ *pitch = MIN_PITCH_6K4; move16();
+ FOR (n = MIN_PITCH_6K4 + 1; n <= MAX_PITCH_6K4; n++)
+ {
+ L_tmp = Mpy_32_16_lc3plus(ac[n - MIN_PITCH_6K4], olpa_ac_weighting[n - MIN_PITCH_6K4]);
+ L_tmp2 = L_sub_sat(L_tmp, max32);
+ if (L_tmp2 > 0)
+ {
+ *pitch = n; move16();
+ }
+ max32 = L_max(L_tmp, max32);
+ }
+
+ /* Compute normalized correlation */
+ sum0 = L_mult0(s6k4[0], s6k4[0 - *pitch]);
+ sum1 = L_mac0(1, s6k4[0 - *pitch], s6k4[0 - *pitch]);
+ sum2 = L_mac0(1, s6k4[0], s6k4[0]);
+ for (m = 1; m < acflen; m++)
+ {
+ sum0 = L_mac0(sum0, s6k4[m], s6k4[m - *pitch]);
+ sum1 = L_mac0(sum1, s6k4[m - *pitch], s6k4[m - *pitch]);
+ sum2 = L_mac0(sum2, s6k4[m], s6k4[m]);
+ }
+ scale1 = norm_l(sum1);
+ scale2 = norm_l(sum2);
+ sum1 = L_shl_pos(sum1, scale1);
+ sum2 = L_shl_pos(sum2, scale2);
+ prod = Mpy_32_32_lc3plus(sum1, sum2);
+ shift = norm_l(prod);
+ prod = L_shl_pos(prod, shift);
+ prod_exp = sub(62, add(add(scale1, scale2), shift));
+ inv = Isqrt(prod, &prod_exp);
+ scale0 = norm_l(sum0);
+ sum0 = L_shl_pos(sum0, scale0);
+ prod = Mpy_32_32_lc3plus(sum0, inv);
+ prod_exp = add(sub(31, scale0), prod_exp);
+ test();
+ IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0)
+ {
+ *normcorr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16();
+ }
+ ELSE
+ {
+ *normcorr = 32767; move16();
+ }
+
+ /* Second try in the neighborhood of the previous pitch */
+ min_pitch = s_max(MIN_PITCH_6K4, sub(*mem_pitch, 4));
+ max_pitch = s_min(MAX_PITCH_6K4, add(*mem_pitch, 4));
+
+ max32 = ac[min_pitch - MIN_PITCH_6K4]; move32();
+ pitch2 = min_pitch; move16();
+ FOR (n = min_pitch + 1; n <= max_pitch; n++)
+ {
+ L_tmp = L_sub_sat(ac[n - MIN_PITCH_6K4], max32);
+ if (L_tmp > 0)
+ {
+ pitch2 = n; move16();
+ }
+ max32 = L_max(ac[n - MIN_PITCH_6K4], max32);
+ }
+ IF (sub(*pitch, pitch2) != 0)
+ {
+ sum0 = L_mult0(s6k4[0], s6k4[0 - pitch2]);
+ sum1 = L_mac0(1, s6k4[0 - pitch2], s6k4[0 - pitch2]);
+ sum2 = L_mac0(1, s6k4[0], s6k4[0]);
+ for (m = 1; m < acflen; m++)
+ {
+ sum0 = L_mac0(sum0, s6k4[m], s6k4[m - pitch2]);
+ sum1 = L_mac0(sum1, s6k4[m - pitch2], s6k4[m - pitch2]);
+ sum2 = L_mac0(sum2, s6k4[m], s6k4[m]);
+ }
+ scale1 = norm_l(sum1);
+ scale2 = norm_l(sum2);
+ sum1 = L_shl_pos(sum1, scale1);
+ sum2 = L_shl_pos(sum2, scale2);
+ prod = Mpy_32_32_lc3plus(sum1, sum2);
+ shift = norm_l(prod);
+ prod = L_shl_pos(prod, shift);
+ prod_exp = sub(62, add(add(scale1, scale2), shift));
+ inv = Isqrt(prod, &prod_exp);
+ scale0 = norm_l(sum0);
+ sum0 = L_shl_pos(sum0, scale0);
+ prod = Mpy_32_32_lc3plus(sum0, inv);
+ prod_exp = add(sub(31, scale0), prod_exp);
+ test();
+ IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0)
+ {
+ normcorr2 = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16();
+ }
+ ELSE
+ {
+ normcorr2 = 32767; move16();
+ }
+ IF (sub(normcorr2, mult_r(*normcorr, 27853)) > 0)
+ {
+ *pitch = pitch2; move16();
+ *normcorr = normcorr2; move16();
+ }
+ }
+
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ SWITCH(frame_dms)
+ {
+ case 50:
+ if(*pitch_flag == 1) {
+ *mem_pitch = *pitch; move16();
+ *pitch_flag = 0;
+ }
+ else {
+ *pitch_flag += 1;
+ }
+ break;
+
+ case 25:
+ if (*pitch_flag == 3) {
+ *mem_pitch = *pitch; move16();
+ *pitch_flag = 0;
+ }
+ else {
+ *pitch_flag += 1;
+ }
+ break;
+
+ default:
+#endif
+ *mem_pitch = *pitch; move16();
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ }
+#endif
+
+ /* Update memory */
+ basop_memmove(mem_s6k4, &mem_s6k4[len2], mem_in_len * sizeof(Word16));
+
+ /* Upsample pitch by a factor of 2 (6.4kHz -> 12.8kHz) */
+ *pitch = shl_pos(*pitch, 1); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/pc_apply_fx.c b/lib_lc3plus/pc_apply_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..42ddfb243fb0daf5b2c77abe83915e92ae220af4
--- /dev/null
+++ b/lib_lc3plus/pc_apply_fx.c
@@ -0,0 +1,315 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "constants.h"
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE
+static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen);
+#else
+static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen);
+#endif
+
+
+void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e,
+ Word16 *pc_nbLostFramesInRow)
+{
+ Counter i;
+ Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr;
+ Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low;
+ Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e;
+ Word32 tmp32, ener_curr_gg2, ener_prev_gg2;
+ Word16 fac_local, fac_local_e;
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Counter i;
+ Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr;
+ Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low;
+ Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e;
+ Word32 tmp32, ener_curr_gg2, ener_prev_gg2;
+ Word16 fac_local, fac_local_e;
+ };
+ Dyn_Mem_In("processPCapply_fx", sizeof(struct _dynmem));
+#endif
+
+ assert(spec_inv_idx >= 0);
+
+ *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1);
+
+ tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7);
+ global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1);
+ global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000)));
+
+ /** Calculate rescaling factor **/
+
+ /* mean_nrg_low = mean(q_d_prev(1:spec_inv_idx-1).^2);
+ mean_nrg_high = mean(q_d_prev(spec_inv_idx:end).^2); */
+ s = getScaleFactor16(q_old_d_fx, yLen);
+
+ mean_nrg_low = 0;
+ move32();
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+ tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4));
+ mean_nrg_low = L_mac0(mean_nrg_low, tmp16, tmp16); /* exp = 2s - 8 */
+ }
+
+ mean_nrg_high = 0;
+ move32();
+ FOR (i = spec_inv_idx; i < yLen; i++)
+ {
+ tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4));
+ mean_nrg_high = L_mac0(mean_nrg_high, tmp16, tmp16); /* exp = 2s - 8 */
+ }
+
+ IF (sub(spec_inv_idx, sub(yLen, spec_inv_idx)) < 0)
+ {
+ c = div_s(spec_inv_idx, sub(yLen, spec_inv_idx));
+ mean_nrg_high = Mpy_32_16_lc3plus(mean_nrg_high, c); /* exp = 2s - 8 */
+ }
+ ELSE
+ {
+ c = div_s(sub(yLen, spec_inv_idx), spec_inv_idx);
+ mean_nrg_low = Mpy_32_16_lc3plus(mean_nrg_low, c); /* exp = 2s - 8 */
+ }
+
+ /* ener_prev = sum(q_old_res(1:spec_inv_idx-1).^2);
+ ener_curr = sum( q_res(1:spec_inv_idx-1).^2); */
+ s = getScaleFactor16(q_old_res_fx, spec_inv_idx);
+ ener_prev = 0; move32();
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+ tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4));
+ ener_prev = L_mac0(ener_prev, tmp16, tmp16); /* exp = - (2s - 8 - 2**q_old_res_fx_exp) */
+ }
+
+ ener_curr = 0;
+ move32();
+
+#ifdef ENABLE_HR_MODE
+ s2 = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx);
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+ tmp16 = extract_h(L_shl_sat(q_res_fx[i], sub(s2, 4)));
+ ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */
+ }
+ s2 = s2 - 16;
+#else
+ s2 = getScaleFactor16(q_res_fx, spec_inv_idx);
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+ tmp16 = shl_sat(q_res_fx[i], sub(s2, 4));
+ ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */
+ }
+#endif
+
+
+ s = shl(sub(s, *q_old_res_fx_exp), 1);
+ s2 = shl(s2, 1);
+ s3 = s_max(s, s2);
+ ener_prev = L_shr_sat(ener_prev, sub(s3, s2));
+ ener_curr = L_shr_sat(ener_curr, sub(s3, s));
+
+ /* fac = 1; */
+ *fac = 1;
+ /* if ener_prev > 0 */
+ IF ( ener_prev > 0 )
+ {
+ /* fac = sqrt(ener_curr/ener_prev); */
+ s = getScaleFactor32_lc3plus(&ener_prev, 1);
+ s2 = getScaleFactor32_lc3plus(&ener_curr, 1);
+ s3 = s_min(s, s2);
+ tmp16 = extract_h(L_shl_sat(ener_curr, s3));
+ tmp16_2 = extract_h(L_shl_sat(ener_prev, s3));
+
+ *fac_e = 0; move16();
+ if ( tmp16_2 == 0) {
+ tmp16_2 = 32767; move16();
+ *fac_e = 15; move16();
+ } else {
+ tmp16_2 = Inv16_lc3plus(tmp16_2, fac_e);
+ }
+
+ *fac = mult(tmp16, tmp16_2);
+
+ IF (sub(*fac, 32767) < 0)
+ {
+ *fac = Sqrt16_lc3plus(*fac, fac_e); move16();
+ }
+ }
+
+ /* fac_local = fac; */
+ fac_local = *fac;
+ fac_local_e = *fac_e;
+
+ /* if (mean_nrg_low > mean_nrg_high) && (ener_prev * prev_gg^2 > ener_curr * gg^2) */
+ prev_gg2 = mult(prev_gg, prev_gg);
+ prev_gg2_e = shl(prev_gg_e, 1);
+ ener_prev_gg2 = Mpy_32_16_lc3plus(ener_prev, prev_gg2); /* exp = prev_gg2_e */
+
+ gg2 = mult(global_gain, global_gain);
+ gg2_e = shl(global_gain_e, 1);
+ ener_curr_gg2 = Mpy_32_16_lc3plus(ener_curr, gg2); /* exp = gg2_e */
+
+ s3 = s_max(prev_gg2_e, gg2_e);
+ ener_prev_gg2 = L_shr_sat(ener_prev_gg2, sub(s3, prev_gg2_e));
+ ener_curr_gg2 = L_shr_sat(ener_curr_gg2, sub(s3, gg2_e));
+
+
+ test();
+ IF ( (L_sub(mean_nrg_low, mean_nrg_high) <= 0) || (L_sub(ener_prev_gg2, ener_curr_gg2) <= 0) )
+ {
+ /* fac = prev_gg/gg; */
+ s = global_gain_e; move16();
+ inv_gain = Inv16_lc3plus(global_gain, &s);
+ fac_local = mult(prev_gg, inv_gain);
+ fac_local_e = add(s, prev_gg_e);
+ }
+
+ /* write synthesized samples */
+ *q_old_res_fx_exp = add(*q_old_res_fx_exp, fac_local_e);
+ thr = shl_sat(20480, sub(-15, *q_old_res_fx_exp));
+ FOR (i = spec_inv_idx; i < yLen; i++)
+ {
+ q_res_fx[i] = extract_h(L_mult(q_old_res_fx[i] /* exp = q_old_res_fx_exp' */, fac_local /* exp = fac_e */)); /* exp = q_old_res_fx_exp */
+
+ IF (sub(abs_s(q_res_fx[i]), thr) < 0)
+ {
+ q_res_fx[i] = 0;
+ move16();
+ }
+ }
+
+#ifdef ENABLE_HR_MODE
+ s = getScaleFactor32_withNegativeScaling(&q_res_fx[0], spec_inv_idx) - 16; /* exp = 0 */
+ s2 = getScaleFactor32_withNegativeScaling(&q_res_fx[spec_inv_idx],
+ sub(yLen, spec_inv_idx)) - 16; /* exp = q_old_res_fx_exp */
+#else
+ s = getScaleFactor16_withNegativeScaling(&q_res_fx[0], spec_inv_idx); /* exp = 0 */
+ s2 = getScaleFactor16_withNegativeScaling(&q_res_fx[spec_inv_idx],
+ sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */
+#endif
+
+ s3 = add(s, *q_old_res_fx_exp);
+ IF (sub(s3, s2) > 0)
+ {
+ tmp16 = sub(s3, s2);
+ s = sub(s, tmp16);
+ s3 = sub(s3, tmp16);
+ }
+ *q_fx_exp = sub(15, s);
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ s = add(s, 16);
+ s3 = add(s3, 16);
+#endif
+
+ s = s_max(s, -31);
+ s = s_min(s, 31);
+ s3 = s_max(s3, -31);
+ s3 = s_min(s3, 31);
+
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ q_d_fx[i] = L_shl(q_res_fx[i], s);
+#else
+ q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s);
+#endif
+ move32();
+ }
+ FOR (; i < yLen; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ q_d_fx[i] = L_shl(q_res_fx[i], s3);
+#else
+ q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s3);
+#endif
+ move32();
+ }
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+#ifndef ENABLE_HR_MODE
+static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen)
+{
+ Counter i;
+ Dyn_Mem_Deluxe_In(Word16 tmp, shift; Word16 x_min, x_max;);
+
+ x_max = 0;
+ move16();
+ x_min = 0;
+ move16();
+
+ FOR (i = 0; i < dataLen; i++)
+ {
+ if (data16[i] > 0)
+ x_max = s_max(x_max, data16[i]);
+ if (data16[i] < 0)
+ x_min = s_min(x_min, data16[i]);
+ }
+
+ tmp = s_max(x_max, negate(x_min));
+ shift = norm_s(tmp);
+ if (tmp == 0)
+ {
+ shift = 15;
+ move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+
+ return shift;
+}
+
+#else
+static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen)
+{
+ Counter i;
+ Dyn_Mem_Deluxe_In(Word32 tmp, shift; Word32 x_min, x_max;);
+
+ x_max = L_add(0, 0);
+ x_min = L_add(0, 0);
+
+ FOR (i = 0; i < dataLen; i++)
+ {
+ if (data32[i] >= 0)
+ x_max = L_max(x_max, data32[i]);
+ if (data32[i] < 0)
+ x_min = L_min(x_min, data32[i]);
+ }
+
+ tmp = L_max(x_max, L_negate(x_min));
+ shift = norm_l(tmp);
+ if (tmp == 0)
+ {
+ shift = 31;
+ move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+
+ return shift;
+}
+#endif
diff --git a/lib_lc3plus/pc_classify_fx.c b/lib_lc3plus/pc_classify_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..28898f9638abe71bd6e23814681d0a8364654218
--- /dev/null
+++ b/lib_lc3plus/pc_classify_fx.c
@@ -0,0 +1,260 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "constants.h"
+#include "functions.h"
+
+#define BLOCK_SIZE 3
+#define THR1 8
+#define FAC 9830 /* 0.3 */
+
+void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover);
+
+void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[],
+ Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 maxPitchBin, xover;
+ Counter i;
+ Word16 s, tmp16, full_nrg16, part_nrg16;
+ Word32 full_nrg, part_nrg;
+ );
+
+ /* Apply classifier only if lower than 2kHz signal */
+ IF (sub(DEPR_i_mult(spec_inv_idx, 10), shl_pos(frame_dms, 2)) < 0 )
+ {
+ IF (sub(stab_fac, 16384 /* 0.5 */) < 0)
+ {
+ *bfi = 1;
+ }
+ ELSE IF (sub(pitch_present, 1) == 0)
+ {
+ maxPitchBin = 8; move16();
+ IF (sub(frame_dms, 50) == 0)
+ {
+ maxPitchBin = 4; move16();
+ }
+
+ /* avoid phase discontinuity in low frequencies */
+ peakDetector_fx(q_old_d_fx, yLen, &xover);
+ test();
+ IF (sub(spec_inv_idx, xover) < 0 || sub(spec_inv_idx, maxPitchBin) < 0)
+ {
+ *bfi = 1;
+ }
+ }
+ ELSE
+ {
+ s = getScaleFactor16(q_old_res_fx, yLen);
+
+ part_nrg = 0; move32();
+ FOR (i = 0; i < spec_inv_idx; i++)
+ {
+ tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4));
+ part_nrg = L_mac0(part_nrg, tmp16, tmp16); /* exp = 2s - 8 */
+ }
+
+ full_nrg = part_nrg; move32();
+ FOR (i = spec_inv_idx; i < yLen; i++)
+ {
+ tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4));
+ full_nrg = L_mac0(full_nrg, tmp16, tmp16); /* exp = 2s - 8 */
+ }
+
+ s = getScaleFactor32_lc3plus(&full_nrg, 1);
+ full_nrg16 = extract_h(L_shl(full_nrg, s));
+ part_nrg16 = extract_h(L_shl(part_nrg, s));
+
+ tmp16 = mult(full_nrg16, 9830 /* 0.3 */);
+
+ IF (part_nrg16 < tmp16)
+ {
+ *bfi = 1;
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i, j;
+ Word16 tmp16, c, s, s2, mean_block_nrg16;
+ Word32 maxPeak, tmp32;
+ Word32 mean_block_nrg, block_cent;
+ Word16 cur_max, prev_max, next_max;
+ );
+
+ *xover = 0;
+
+ s = getScaleFactor16(in_sig, yLen);
+
+ mean_block_nrg = 0; move32();
+ FOR (i = 0; i < yLen; i++)
+ {
+ tmp16 = shl_sat(in_sig[i], sub(s, 4));
+ mean_block_nrg = L_mac0(mean_block_nrg, tmp16, tmp16); /* exp = 2s - 8 */
+ }
+
+ s2 = getScaleFactor16(&yLen, 1);
+ c = shl(yLen, s2);
+ mean_block_nrg16 = div_l(mean_block_nrg, c); /* exp = 2s - 8 - s2 - 1 */
+ mean_block_nrg = L_shl(L_mult0(mean_block_nrg16, BLOCK_SIZE * THR1), add(4, s2)); /* exp = 2s - 5 */
+
+ maxPeak = 0; move32();
+ c = sub(yLen, 2 * BLOCK_SIZE);
+
+ test();
+ IF (abs_s(in_sig[0]) >= abs_s(in_sig[1]))
+ {
+ block_cent = 0; move32();
+ FOR (j = 0; j <= 1; j++)
+ {
+ tmp16 = shl_sat(in_sig[j], sub(s, 2));
+ block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */
+ }
+ block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */
+
+ IF (L_sub(block_cent, mean_block_nrg) > 0)
+ {
+ cur_max = abs_s(in_sig[0]);
+ cur_max = MAX(abs_s(in_sig[1]), cur_max);
+
+ next_max = abs_s(in_sig[-1 + BLOCK_SIZE]);
+ next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 1]), next_max);
+ next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 2]), next_max);
+
+ IF (sub(cur_max, next_max) > 0)
+ {
+ maxPeak = block_cent; move32();
+ *xover = 1;
+ }
+ }
+ }
+
+ FOR (i = 0; i < BLOCK_SIZE; i++)
+ {
+ test();
+ IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2]))
+ {
+ block_cent = 0; move32();
+ FOR (j = 0; j < BLOCK_SIZE; j++)
+ {
+ tmp16 = shl_sat(in_sig[i + j], sub(s, 2));
+ block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */
+ }
+ block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */
+
+ IF (L_sub(block_cent, mean_block_nrg) > 0)
+ {
+ cur_max = abs_s(in_sig[i]);
+ cur_max = MAX(abs_s(in_sig[i + 1]), cur_max);
+ cur_max = MAX(abs_s(in_sig[i + 2]), cur_max);
+
+ prev_max = 0; move16();
+ FOR (j = i - BLOCK_SIZE; j <= i - 1; j++)
+ {
+ IF (j > 0)
+ {
+ prev_max = MAX(abs_s(in_sig[j]), prev_max);
+ }
+ }
+
+ next_max = abs_s(in_sig[i + BLOCK_SIZE]);
+ next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max);
+ next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max);
+
+ test();
+ IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0)
+ {
+ IF (L_sub(block_cent, maxPeak) >= 0)
+ {
+ maxPeak = block_cent; move32();
+ *xover = sub(add(i, BLOCK_SIZE), 1);
+ }
+ ELSE
+ {
+ tmp32 = L_mult(FAC, extract_h(maxPeak));
+
+ tmp16 = extract_l(L_shr(maxPeak, 1));
+ tmp16 = s_and(tmp16, 0x7fff);
+ tmp16 = mult(FAC, tmp16);
+ tmp32 = L_add_sat(tmp32, tmp16);
+
+ IF (L_sub(block_cent, tmp32) > 0)
+ {
+ *xover = sub(add(i, BLOCK_SIZE), 1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ FOR (i = BLOCK_SIZE; i <= c; i++)
+ {
+ test();
+ IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2]))
+ {
+ block_cent = 0; move32();
+ FOR (j = 0; j < BLOCK_SIZE; j++)
+ {
+ tmp16 = shl_sat(in_sig[i + j], sub(s, 2));
+ block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */
+ }
+ block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */
+
+ IF (L_sub(block_cent, mean_block_nrg) > 0)
+ {
+ cur_max = abs_s(in_sig[i]);
+ cur_max = MAX(abs_s(in_sig[i + 1]), cur_max);
+ cur_max = MAX(abs_s(in_sig[i + 2]), cur_max);
+
+ prev_max = abs_s(in_sig[i - BLOCK_SIZE]);
+ prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 1]), prev_max);
+ prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 2]), prev_max);
+
+ next_max = abs_s(in_sig[i + BLOCK_SIZE]);
+ next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max);
+ next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max);
+
+ test();
+ IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0)
+ {
+ IF (L_sub(block_cent, maxPeak) >= 0)
+ {
+ maxPeak = block_cent; move32();
+ *xover = sub(add(i, BLOCK_SIZE), 1);
+ }
+ ELSE
+ {
+ tmp32 = L_mult(FAC, extract_h(maxPeak));
+
+ tmp16 = extract_l(L_shr(maxPeak, 1));
+ tmp16 = s_and(tmp16, 0x7fff);
+ tmp16 = mult(FAC, tmp16);
+ tmp32 = L_add_sat(tmp32, tmp16);
+
+ IF (L_sub(block_cent, tmp32) > 0)
+ {
+ *xover = sub(add(i, BLOCK_SIZE), 1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
diff --git a/lib_lc3plus/pc_main_fx.c b/lib_lc3plus/pc_main_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..708f79d748a758f4bdef3a2af8d9363e55ae3f6e
--- /dev/null
+++ b/lib_lc3plus/pc_main_fx.c
@@ -0,0 +1,57 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "constants.h"
+#include "functions.h"
+
+void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[],
+ Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 q_old_d_fx[], Word16 spec_inv_idx,
+ Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp,
+ Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf,
+ Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 fac, fac_e;
+ );
+
+ fac = 32767; fac_e = 0;
+
+ IF (sub(*bfi, 2) == 0)
+ {
+ processPCclassify_fx(pitch_present, frame_dms, q_old_d_fx, q_old_res_fx, yLen, spec_inv_idx, stab_fac, bfi);
+ }
+
+ IF (sub(*bfi, 2) == 0)
+ {
+ processPCapply_fx(yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, q_old_d_fx, spec_inv_idx,
+ &fac, &fac_e, q_d_fx, q_fx_exp, gg_idx, gg_idx_off, *prev_gg, *prev_gg_e, pc_nbLostFramesInRow);
+ }
+
+ IF (sub(*bfi, 1) != 0)
+ {
+ processPCupdate_fx(*bfi, yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, spec_inv_idx, gg_idx, gg_idx_off, prev_gg,
+ prev_gg_e, rframe, BW_cutoff_idx_nf, prev_BW_cutoff_idx_nf, fac_ns_idx, prev_fac_ns_fx, fac, fac_e);
+ }
+
+ if (*bfi == 0)
+ {
+ *pc_nbLostFramesInRow = 0; move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
diff --git a/lib_lc3plus/pc_update_fx.c b/lib_lc3plus/pc_update_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..17b719bcd224e8dee2cf0695a8a46ca28dfbefab
--- /dev/null
+++ b/lib_lc3plus/pc_update_fx.c
@@ -0,0 +1,148 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "constants.h"
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE
+
+void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */
+ Word16 y[], /* o : scaled signal output Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+)
+{
+ Counter i;
+ Word16 tmp;
+
+ if (exp0 == 0)
+ {
+ for (i = 0; i < lg; i++)
+ {
+ y[i] = extract_h(x[i]);
+ }
+
+ return;
+ }
+
+ tmp = s_max(exp0, -31);
+ tmp = s_min(tmp, 31);
+
+ for (i = 0; i < lg; i++)
+ {
+ y[i] = extract_h(L_shr_r(x[i], -tmp));
+ }
+}
+#endif
+
+void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 q_res_fx[],
+#else
+ Word16 q_res_fx[],
+#endif
+ Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off,
+ Word16 *prev_gg, Word16 *prev_gg_e, Word16 rframe, Word16 *BW_cutoff_idx_nf,
+ Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 fac,
+ Word16 fac_e)
+{
+ Word16 global_gain, global_gain_e, s, s2, s3, tmp16;
+ Word32 tmp32;
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Word16 global_gain, global_gain_e, s, s2, s3, tmp16;
+ Word32 tmp32;
+ };
+ Dyn_Mem_In("processPCupdate_fx", sizeof(struct _dynmem));
+#endif
+
+ tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7);
+ global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1);
+ global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000)));
+
+ *prev_gg = global_gain; move16();
+ *prev_gg_e = global_gain_e; move16();
+
+#ifdef ENABLE_HR_MODE
+ s = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx); /* exp = 0 */
+#else
+ s = getScaleFactor16(q_res_fx, spec_inv_idx); /* exp = 0 */
+#endif
+
+ IF (bfi == 0)
+ {
+ *q_old_res_fx_exp = negate(s);
+#ifdef ENABLE_HR_MODE
+ Copy_Scale_sig_32(q_res_fx, q_old_res_fx, yLen, s);
+ *q_old_res_fx_exp = *q_old_res_fx_exp + 16;
+#else
+ Copy_Scale_sig(q_res_fx, q_old_res_fx, yLen, s);
+#endif
+ }
+ ELSE
+ {
+#ifdef ENABLE_HR_MODE
+ s2 = getScaleFactor32_lc3plus(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */
+ IF (s2 == 0)
+ s2 = 16;
+ s3 = add(s, *q_old_res_fx_exp);
+ IF (sub(s3, s2) > 0)
+ {
+ tmp16 = sub(s3, s2);
+ s = sub(s, tmp16);
+ }
+ s2 = add(s, *q_old_res_fx_exp);
+ *q_old_res_fx_exp = negate(s) + 16;
+
+
+ if (s2 > -32)
+ {
+ Copy_Scale_sig_32(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2);
+ }
+#else
+ s2 = getScaleFactor16(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */
+ s3 = add(s, *q_old_res_fx_exp);
+ IF (sub(s3, s2) > 0)
+ {
+ tmp16 = sub(s3, s2);
+ s = sub(s, tmp16);
+ }
+ s2 = add(s, *q_old_res_fx_exp);
+ *q_old_res_fx_exp = negate(s);
+
+ s = s_max(s_min(s, 15), -15);
+ s2 = s_max(s_min(s2, 15), -15);
+ Copy_Scale_sig(q_res_fx, q_old_res_fx, spec_inv_idx, s);
+ Copy_Scale_sig(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2);
+#endif
+ }
+
+ IF (rframe == 0)
+ {
+ *prev_BW_cutoff_idx_nf = *BW_cutoff_idx_nf;
+ *prev_fac_ns_fx = shl_pos(sub(8, fac_ns_idx), 11);
+ }
+ ELSE IF(sub(bfi, 2) == 0 && sub(*BW_cutoff_idx_nf, *prev_BW_cutoff_idx_nf) != 0
+ && sub(spec_inv_idx, yLen) < 0)
+ {
+ *BW_cutoff_idx_nf = *prev_BW_cutoff_idx_nf;
+ *prev_fac_ns_fx = shl_sat(mult(*prev_fac_ns_fx, fac), fac_e);
+ *prev_fac_ns_fx = s_max(*prev_fac_ns_fx, 2048);
+ *prev_fac_ns_fx = s_min(*prev_fac_ns_fx, 16384);
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/per_band_energy_fx.c b/lib_lc3plus/per_band_energy_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..14e853212400030e2b5fae2b012864660ac7ae84
--- /dev/null
+++ b/lib_lc3plus/per_band_energy_fx.c
@@ -0,0 +1,275 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "rom_basop_util.h"
+
+void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp,
+ const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+)
+{
+ Dyn_Mem_Deluxe_In(Counter i, k, band; Word16 s; Word16 s1; Word16 s2; Word32 nrg; Word16 smax; Word16 tmp16;
+ Word16 nbands; Word16 maxBwBin; Word16 stopBand; Word16 bandsOffsetOne; Word16 bandsOffsetTwo;
+ Word16 * d2_band_fx_exp;);
+
+
+ d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC bytes */
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ maxBwBin = MAX_BW_HR;
+ fs_idx = fs_idx + 1;
+ move16();
+ }
+ else
+#endif
+ {
+ maxBwBin = MAX_BW;
+ move16();
+ }
+
+ SWITCH (frame_dms)
+ {
+ case 25: maxBwBin = maxBwBin >> 2; move16();
+ {
+ bandsOffsetOne = bands_offset_with_one_max_2_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_2_5ms[fs_idx];
+ move16();
+ }
+ BREAK;
+ case 50: maxBwBin = maxBwBin >> 1; move16();
+ {
+ bandsOffsetOne = bands_offset_with_one_max_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_5ms[fs_idx];
+ move16();
+ }
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ maxBwBin = (maxBwBin >> 2) * 3; move16();
+ bandsOffsetOne = bands_offset_with_one_max_7_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_7_5ms[fs_idx];
+ move16();
+ BREAK;
+#endif
+ default: /* 100 */
+ {
+ bandsOffsetOne = bands_offset_with_one_max[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max[fs_idx];
+ move16();
+ }
+ BREAK;
+ }
+
+ IF (sub(linear, 1) == 0)
+ {
+
+ #ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ fs_idx = fs_idx - 1;
+ }
+ #endif
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ bandsOffsetOne = bands_offset_with_one_max_lin_2_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_lin_2_5ms[fs_idx];
+ move16();
+ BREAK;
+ case 50:
+ bandsOffsetOne = bands_offset_with_one_max_lin_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_lin_5ms[fs_idx];
+ move16();
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ bandsOffsetOne = bands_offset_with_one_max_lin_7_5ms[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_lin_7_5ms[fs_idx];
+ move16();
+ BREAK;
+#endif
+ case 100:
+ bandsOffsetOne = bands_offset_with_one_max_lin[fs_idx];
+ move16();
+ bandsOffsetTwo = bands_offset_with_two_max_lin[fs_idx];
+ move16();
+ BREAK;
+ }
+ }
+
+ /* start processing with band offsets == 1 */
+ FOR (band = 0; band < bandsOffsetOne; band++)
+ {
+ ASSERT((band_offsets[band + 1] - band_offsets[band]) == 1);
+ ASSERT(band < maxBwBin);
+
+ s2 = 15;
+ move16();
+ s = norm_l(d_fx[band]);
+ if (d_fx[band] != 0)
+ s2 = s_min(s2, s);
+
+ tmp16 = extract_h(L_shl_pos(d_fx[band], s2));
+
+ d2_fx[band] = L_mult0(tmp16, tmp16);
+ move32();
+ d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
+ move16();
+ }
+
+ /* start processing with band offsets == 2 */
+ i = bandsOffsetOne;
+ move16();
+ FOR (; band < bandsOffsetTwo; band++)
+ {
+ ASSERT((band_offsets[band + 1] - band_offsets[band]) == 2);
+ IF (sub(add(i, 1), maxBwBin) >= 0)
+ {
+ IF (sub(i, maxBwBin) >= 0)
+ {
+ d2_fx[band] = 0;
+ move32();
+ d2_band_fx_exp[band] = sub(1, shl_pos(15, 1));
+ move16();
+ }
+ ELSE
+ {
+ s2 = 15;
+ move16();
+ s = norm_l(d_fx[band]);
+ if (d_fx[band] != 0)
+ s2 = s_min(s2, s);
+
+ tmp16 = extract_h(L_shl_pos(d_fx[band], s2));
+
+ d2_fx[band] = L_mult0(tmp16, tmp16);
+ move32();
+ d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
+ move16();
+ }
+ }
+ ELSE
+ {
+ ASSERT(i + 1 < maxBwBin);
+
+ s2 = 15;
+ move16();
+ s = norm_l(d_fx[i]);
+ if (d_fx[i] != 0)
+ s2 = s_min(s2, s);
+ s = norm_l(d_fx[i + 1]);
+ if (d_fx[i + 1] != 0)
+ s2 = s_min(s2, s);
+
+ tmp16 = extract_h(L_shl_pos(d_fx[i], s2));
+ nrg = L_mult0(tmp16, tmp16);
+ nrg = L_min(nrg, 0x3FFFFFFF);
+ tmp16 = extract_h(L_shl_pos(d_fx[i + 1], s2));
+
+ d2_fx[band] = L_shr_pos(L_mac0(nrg, tmp16, tmp16), 1);
+ move32();
+ d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
+ move16();
+ }
+ i = add(i, 2);
+ }
+
+ /* proceed with band offsets > 2 */
+ FOR (; band < n_bands; band++)
+ {
+ /* normalization */
+ k = i;
+ move16();
+ s1 = 15;
+ move16();
+
+ stopBand = s_min(band_offsets[band + 1], maxBwBin);
+ FOR (; k < stopBand; k++)
+ {
+ s = norm_l(d_fx[k]);
+ if (d_fx[k] != 0)
+ s1 = s_min(s1, s);
+ }
+
+ nbands = sub(band_offsets[band + 1], band_offsets[band]);
+#ifdef ENABLE_HR_MODE
+ if (nbands < 32)
+ {
+ nbands = s_min(s_max(0, nbands), 31);
+ /* specify headroom, it can be reduced by one due to use of L_mac0 */
+ s2 = sub(s1, bands_nrg_scale[nbands]);
+ }
+ else
+ {
+ /* Active only in the 96 kHz case */
+ s2 = sub(s1, 5);
+ }
+#else
+ ASSERT(nbands < 32);
+ nbands = s_min(s_max(0, nbands), 31);
+ /* specify headroom, it can be reduced by one due to use of L_mac0 */
+ s2 = sub(s1, bands_nrg_scale[nbands]);
+#endif
+
+ /* calculate energy per band */
+ nrg = 0;
+ move32();
+
+ FOR (; i < stopBand; i++)
+ {
+ tmp16 = extract_h(L_shl(d_fx[i], s2));
+ nrg = L_mac0(nrg, tmp16, tmp16);
+ }
+ i = band_offsets[band + 1];
+
+ /* calculate mean value of energy */
+ nrg = Mpy_32_16_lc3plus(nrg, InvIntTable[nbands]);
+
+ /* store normalized energy */
+ s = norm_l(nrg);
+ d2_fx[band] = L_shl_pos(nrg, s);
+ move32();
+ d2_band_fx_exp[band] = sub(1, add(shl_pos(s2, 1), s));
+ move16();
+ }
+
+ /* Determine maximum exponent and rescale band energies */
+ smax = -31;
+ move16();
+ FOR (band = 0; band < n_bands; band++)
+ {
+ smax = s_max(smax, d2_band_fx_exp[band]);
+ }
+ FOR (band = 0; band < n_bands; band++)
+ {
+ d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31));
+ move32();
+ }
+
+ /* Save exponent for all bands */
+ *d2_fx_exp = s_max(add(shl_pos(d_fx_exp, 1), smax), -32);
+ move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/plc_apply_fx.c b/lib_lc3plus/plc_apply_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..9430d155e1b9d774d24a1bc0ee6b4b824723720e
--- /dev/null
+++ b/lib_lc3plus/plc_apply_fx.c
@@ -0,0 +1,419 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "constants.h"
+#include "functions.h"
+
+void processPLCapply_fx(
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 *concealMethod,
+#else
+ Word16 concealMethod,
+#endif
+ Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi,
+ Word16 frame_length, Word16 la_zeroes,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[],
+#else
+ const Word16 w[],
+#endif
+ Word16 x_fx[], Word16 ola_mem[],
+ Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int,
+ Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd,
+ Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ , Word32 rel_pitch_change
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , Word16 *alpha_type_2_table
+#endif
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 *d2_fx;
+ Word32 *q_old_d_fx32;
+ Word32 *r_fx;
+ Word32 *tdc_A_32;
+ Word16 d2_fx_exp;
+ Word16 r_fx_exp;
+ Word16 Q_syn;
+ Word8 * buffer_perBandEnergy, *buffer_preEmphasis, *buffer_InverseODFT, *buffer_Levinson,
+ *buffer_tdac, *buffer_phecu;
+ Word16 y_e; /*exponent of L_ecu_rec */
+ Word16 tmp_is_trans[2]; /* may be changed to a single variable */
+ Word16 env_stab;
+
+ Word16 n_bands, prev_bfi_plc2;
+ const Word16 *band_offsets;
+ Word32 * L_ecu_rec; /* local xtda output is MAX_LEN -> input buffer,
+ as tmp buffer for w32 fft MAX_LPROT */
+ );
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 consecutiveLostThreshold = 0;
+#endif
+
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ Word16 thresh_tdc_cnt;
+ Word16 thresh_ns_cnt;
+ Word16 thresh_tdc_ns_cnt;
+#endif
+
+ band_offsets = NULL;
+
+ d2_fx = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER_PLC */
+ q_old_d_fx32 = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * MAX_BW */
+ r_fx = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * (M + 1) */
+ tdc_A_32 = (Word32 *)scratchAlign(r_fx, sizeof(*r_fx) * (M + 1)); /* Size = 4 * (M + 1) */
+
+ L_ecu_rec = (Word32 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 4 * MAX_LPROT bytes */
+
+ buffer_perBandEnergy =
+ (Word8 *)scratchAlign(q_old_d_fx32, sizeof(*q_old_d_fx32) * (MAX_LEN)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */
+ buffer_preEmphasis =
+ (Word8 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */
+ buffer_InverseODFT = buffer_preEmphasis; /* Size = 640 bytes */
+ buffer_Levinson = buffer_preEmphasis; /* Size = 4 * (M + 1) */
+
+ buffer_tdac = scratchBuffer; /* Size = 2 * MAX_LEN bytes */
+ buffer_phecu = scratchBuffer; /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */
+ /* Buffers overlap since they are not used at once */
+
+
+ UNUSED(ns_cum_alpha);
+ UNUSED(ns_seed);
+
+ /* Apply/Prepare PLC in bfi-case */
+ IF (sub(bfi, 1) == 0)
+ {
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ SWITCH(frame_dms)
+ {
+ case 25:
+ consecutiveLostThreshold = 16;
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT;
+ thresh_ns_cnt = THRESH_025_DMS_NS_CNT;
+ thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT;
+#endif
+ break;
+ case 50: consecutiveLostThreshold = 8;
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT;
+ thresh_ns_cnt = THRESH_050_DMS_NS_CNT;
+ thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT;
+#endif
+ break;
+ case 75: consecutiveLostThreshold = 6;
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT;
+ thresh_ns_cnt = THRESH_075_DMS_NS_CNT;
+ thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT;
+#endif
+ break;
+ case 100: consecutiveLostThreshold = 4;
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT;
+ thresh_ns_cnt = THRESH_100_DMS_NS_CNT;
+ thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT;
+#endif
+ break;
+ default: assert(0);
+ }
+
+ IF (sub(fs_idx, 2) == 0 || sub(fs_idx, 4) >= 0)
+ {
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ if (sub(plcAd->longterm_counter_plcTdc, thresh_tdc_cnt) < 0){
+ plcAd->plc_fadeout_type = 1;
+ }
+ else if (sub(plcAd->longterm_counter_plcNsAdv, thresh_ns_cnt) < 0){
+ plcAd->plc_fadeout_type = 1;
+ }
+ else if (sub(plcAd->longterm_counter_plcTdc + plcAd->longterm_counter_plcNsAdv, thresh_tdc_ns_cnt) < 0){
+ plcAd->plc_fadeout_type = 1;
+ }
+ else {
+ plcAd->plc_fadeout_type = 0;
+ }
+
+#else
+ IF (((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT1_FADEOUT)) < 0) ||
+ (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT1_FADEOUT)) < 0)) &&
+ (sub(plcAd->longterm_counter_plcTdc, L_shr_pos(Mpy_32_16_lc3plus(FAC2_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT2_FADEOUT)) < 0))
+ {
+ plcAd->plc_fadeout_type = 0;
+ }
+ ELSE
+ {
+ IF ((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT3_FADEOUT)) > 0) ||
+ (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT3_FADEOUT)) > 0))
+ {
+ plcAd->plc_fadeout_type = 1;
+ } ELSE {
+ plcAd->plc_fadeout_type = 0;
+ }
+ }
+#endif
+
+
+ env_stab = norm_s(plcAd->longterm_analysis_counter_max);
+ IF(sub(shl_pos(plcAd->overall_counter, env_stab), mult(shl_pos(plcAd->longterm_analysis_counter_max, env_stab), PLC_LONGTERM_ANALYSIS_STARTUP_FILL)) < 0)
+ {
+ plcAd->plc_fadeout_type = 0;
+ }
+
+#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS
+ IF (sub(nbLostFramesInRow, consecutiveLostThreshold) >= 0 && sub(plcAd->plc_fadeout_type, 1) == 0)
+ {
+ IF (sub(*concealMethod, LC3_CON_TEC_TDPLC) == 0)
+ {
+ *concealMethod = LC3_CON_TEC_NS_ADV;
+ }
+ }
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ IF (L_sub(rel_pitch_change,REL_PITCH_THRESH) > 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){
+ plcAd->plc_fadeout_type = 2;move16();
+ } ELSE
+#endif
+ IF((sub(nbLostFramesInRow, consecutiveLostThreshold) < 0) && (*concealMethod != LC3_CON_TEC_PHASE_ECU))
+ {
+ plcAd->plc_fadeout_type = 0;
+ }
+ } ELSE {
+ plcAd->plc_fadeout_type = 0; /*fs_idx == 0,1,3 */
+ }
+#endif /* CR8_A_PLC_FADEOUT_TUNING */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ SWITCH (*concealMethod)
+#else
+ SWITCH (concealMethod)
+#endif
+ {
+ case LC3_CON_TEC_PHASE_ECU:
+ ASSERT(frame_dms == 100);
+ /* call phaseEcu */
+ env_stab = 32767; move16(); /* 1.0=stable , 0.0=dynamic Q15*/
+ tmp_is_trans[0] = plcAd->PhECU_short_flag_prev; move16();
+ tmp_is_trans[1] = plcAd->PhECU_short_flag_prev; move16();
+
+ ASSERT(prev_bfi == 0 || prev_bfi == 1|| prev_bfi == 2); /*PC prev_bfi has three states */
+ prev_bfi_plc2 = prev_bfi; move16();
+ if (sub(prev_bfi_plc2, 2) == 0)
+ {
+ prev_bfi_plc2 = 0; move16();
+ }
+
+ ASSERT(prev_bfi_plc2 == 0 || prev_bfi_plc2 == 1); /*PhEcu does not accept prev_bfi == 2 */
+ IF(prev_bfi_plc2 == 0)
+ { /* convert pitch lag info at current fs to a normalized fractional bin-frequency */
+ plcAd->PhECU_f0hzLtpBinQ7 = plc_phEcuSetF0Hz_fx(fs_idx, old_pitch_int, old_pitch_fr); move16();
+
+
+
+ /* first bfi frame calc decoded pcm energy 16,16 ms, in 26 ms buffer separated by 10 ms*/
+
+ { /* compute energy normalization needed for concealment method 2 Xavg and transient analysis */
+
+ /* left */
+ processPLCUpdateXFP_w_E_hist_fx(0, 0,
+ &(plcAd->x_old_tot_fx[ sub(plcAd->max_len_pcm_plc , add(num_FsByResQ0[fs_idx],rectLengthTab[fs_idx] )) ]), plcAd->q_fx_old_exp,0,
+
+ fs_idx,
+ &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx,
+ &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx,
+ &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx);
+
+ /* right */
+ processPLCUpdateXFP_w_E_hist_fx(0, 0, plcAd->PhECU_xfp_fx, plcAd->PhECU_xfp_exp_fx,
+ plcAd->PhECU_margin_xfp, fs_idx,
+ &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx,
+ &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx,
+ &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx);
+ }
+ }
+
+ hq_phase_ecu_fx(
+ plcAd->PhECU_xfp_fx, /* i : only valid first Bfi frame , buffer of previous synt signal length */
+ L_ecu_rec, /* o : reconstructed frame in folded tda domain xtda Word32 Q x */
+ &plcAd->PhECU_time_offs, /* i/o: Sample offset for consecutive frame losses*/
+ plcAd->PhECU_X_sav_fx, /* i(prev_bfi==1)/o(prev_bfi==0): Stored Complex spectrum of prototype frame */
+ &plcAd->PhECU_X_savQ_fx, /* i/o: Q value of stored spectrum */
+ &plcAd->PhECU_num_plocs, /* i/o: Number of identified peaks */
+ plcAd->PhECU_plocs, /* i/o: Peak locations Q0 */
+ plcAd->PhECU_f0est, /* i/o: Interpolated peak locations Q16 */
+ env_stab, /* i : Envelope stability parameter */
+ plcAd->PhECU_f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */
+ plcAd->norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */
+ prev_bfi_plc2, /* i : indicating burst frame error */
+ tmp_is_trans, /* i : flags indicating previous transient frames */
+ plcAd->PhECU_mag_chg_1st, /* i/o: per band magnitude modifier for transients*/
+ NULL, /* o: dbg per band magnitude modifier, incl. burst attenuation */
+ plcAd->PhECU_Xavg, /* i/o: Frequency group average gain to fade to */
+ &plcAd->PhECU_beta_mute, /* o : Factor for long-term mute */
+ fs_idx, /* i : Encoded bandwidth "nb(0),WB,sWB,WB,FB" */
+ frame_length, /* i : frame length */
+ NULL , /* o : seed synch dbg */
+ NULL , /* o : evolved Spectrum dbg */
+ plcAd->PhECU_t_adv, /* i : time adjustment excluding time_offs */
+ PhECU_wins[fs_idx][2], /* i: 2 ms initial part pre_tda = mdct-ana */
+ PhECU_wins[fs_idx][1], /* i: 16 ms pretda combined part IWHR+MDCT-ana */
+ PhECU_wins[fs_idx][0],
+ plcAd->PhECU_xfp_exp_fx,
+ plcAd->max_lprot,
+ plcAd->max_plocs,
+ plcAd->PhECU_L_oold_xfp_w_E_fx,plcAd->PhECU_oold_xfp_w_E_exp_fx, plcAd->PhECU_oold_Ltot_exp_fx,
+ plcAd->PhECU_oold_grp_shape_fx,
+ plcAd->PhECU_L_old_xfp_w_E_fx,plcAd->PhECU_old_xfp_w_E_exp_fx, plcAd->PhECU_old_Ltot_exp_fx,
+ plcAd->PhECU_old_grp_shape_fx,
+ plcAd->PhECU_margin_xfp,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ plcAd->plc_fadeout_type , /* i : fadeout scheme */
+ &(plcAd->PhECU_nonpure_tone_flag), /* i/o : non-pure single tone indicator state */
+#endif
+ buffer_phecu);
+
+ y_e = 18; move16(); /* the fixed exponent (exp) from Lecu_rec from PhaseECU is 18 */
+
+ Processing_ITDA_WIN_OLA(
+ L_ecu_rec, /* i: X_TDA buffer data = "y" DCT-IV output */
+ &y_e, /* i/o: x_tda exponent "y_e" */
+ w, /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */
+ ola_mem, /* i/o: overlap add memory */
+ ola_mem_exp, /* i/o: overlap add exponent */
+ x_fx, /* o: time signal out */
+ LowDelayShapes_n960_len[fs_idx], /* i: window length */
+ frame_length, /* i: block size */
+ sub(frame_length, LowDelayShapes_n960_la_zeroes[fs_idx]) /* i: overlap add buffer size */
+ );
+ *q_fx_exp = y_e; move16(); /* assign updated Q */
+ BREAK;
+
+ case LC3_CON_TEC_TDPLC:
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+ plcAd->tdc_fract = old_pitch_fr; move16();
+ n_bands = s_min(frame_length, MAX_BANDS_NUMBER_PLC);
+ SWITCH (frame_dms)
+ {
+ case 25:
+ band_offsets = bands_offset_lin_2_5ms[fs_idx]; move16();
+ IF (sub(fs_idx, 4) == 0)
+ {
+ n_bands = 60; move16();
+ }
+ BREAK;
+ case 50:
+ band_offsets = bands_offset_lin_5ms[fs_idx]; move16();
+ IF (sub(fs_idx, 2) == 0)
+ {
+ n_bands = 40; move16();
+ }
+ BREAK;
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ band_offsets = bands_offset_lin_7_5ms[fs_idx]; move16();
+# ifdef ENABLE_HR_MODE
+ IF (sub(fs_idx, 5) != 0)
+ {
+# endif
+ IF (sub(fs_idx, 3) != 0)
+ {
+ n_bands = 60; move16();
+ }
+# ifdef ENABLE_HR_MODE
+ }
+# endif
+ BREAK;
+# endif
+ case 100:
+ band_offsets = bands_offset_lin[fs_idx]; move16();
+ BREAK;
+ }
+
+ FOR (i = 0; i < yLen; i++)
+ {
+ q_old_d_fx32[i] = L_deposit_h(q_old_d_fx[i]);
+ }
+
+ /* LPC Analysis */
+ /* calculate per band energy*/
+ processPerBandEnergy_fx(d2_fx, &d2_fx_exp, q_old_d_fx32, *q_old_fx_exp, band_offsets, fs_idx, n_bands,
+ 1, frame_dms, buffer_perBandEnergy
+#ifdef ENABLE_HR_MODE
+ , hrmode
+#endif
+ );
+
+ /* calculate pre-emphasis */
+ processPreEmphasis_fx(d2_fx, &d2_fx_exp, fs_idx, n_bands, frame_dms, buffer_preEmphasis);
+
+ /* inverse ODFT */
+ processInverseODFT_fx(r_fx, &r_fx_exp, d2_fx, d2_fx_exp, n_bands, plcAd->tdc_lpc_order, buffer_InverseODFT);
+
+ /* lag windowing */
+ processLagwin_fx(r_fx, lag_win[fs_idx], plcAd->tdc_lpc_order);
+
+ /* Levinson Durbin */
+ processLevinson_fx(tdc_A_32, r_fx, plcAd->tdc_lpc_order, NULL, NULL, buffer_Levinson);
+
+ /* 32Q27 -> 16Qx */
+ processPLCLpcScaling_fx(tdc_A_32, plcAd->tdc_A, add(plcAd->tdc_lpc_order, 1));
+ }
+
+ /* call TD-PLC */
+ /* Q_syn = plcAd->q_fx_old_exp; */ /* makes q_fx_old_exp
+ available in processTimeDomainConcealment_Apply_fx() for
+ debugging */
+ processTimeDomainConcealment_Apply_fx(
+ old_pitch_int, plcAd->tdc_preemph_fac, plcAd->tdc_A, plcAd->tdc_lpc_order, plcAd->x_old_tot_fx, frame_length, frame_dms,
+ fs_idx, nbLostFramesInRow, sub(frame_length, la_zeroes), plcAd->stab_fac, &plcAd->tdc_fract,
+ &plcAd->tdc_seed,
+ &plcAd->tdc_gain_c, x_fx, &Q_syn, damping,
+ plcAd->max_len_pcm_plc,
+ plcAd->harmonicBuf_fx, plcAd->synthHist_fx, &plcAd->harmonicBuf_Q, scratchBuffer
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+ , plcAd->plc_fadeout_type
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , alpha_type_2_table
+#endif
+);
+
+ /* exponent of TD-PLC output */
+ Q_syn = add(Q_syn, sub(15, plcAd->q_fx_old_exp));
+ *q_fx_exp = sub(15, Q_syn); move16();
+
+ /* TDAC */
+ processTdac_fx(ola_mem, ola_mem_exp, x_fx, *q_fx_exp, w, la_zeroes, frame_length, buffer_tdac);
+ BREAK;
+
+ case LC3_CON_TEC_NS_ADV:
+ *q_fx_exp = *q_old_fx_exp; move16();
+
+ /* call Noise Substitution */
+ processPLCNoiseSubstitution_fx(q_d_fx, q_old_d_fx, yLen);
+
+ BREAK;
+ default: ASSERT(!"Unsupported PLC method!");
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
diff --git a/lib_lc3plus/plc_classify_fx.c b/lib_lc3plus/plc_classify_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbb01826a0be78367cd0b273e0c1383bbb65bc2a
--- /dev/null
+++ b/lib_lc3plus/plc_classify_fx.c
@@ -0,0 +1,424 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+
+static Word32 change_bit_at_position(Word32 value, Word8 bit_position, UWord8 bit)
+{
+ Word32 helper_mask = ~L_shl_pos(1, bit_position);
+ Word32 tmp = L_and(value, helper_mask);
+ tmp = L_or(tmp, L_shl_pos(bit, bit_position));
+ return tmp;
+}
+
+static void update_bit_and_byte_positions(Word16 longterm_analysis_counter_max_bytebuffer, Word8 *byte_position, Word8 *bit_position)
+{
+#ifdef CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC
+ IF (sub(*bit_position, 29) == 0)
+#else
+ IF (sub(*bit_position, 30) == 0)
+#endif
+ {
+ *bit_position = 0; move16();
+
+ if (sub(*byte_position, longterm_analysis_counter_max_bytebuffer) < -1)
+ {
+ *byte_position = add(*byte_position, 1);
+ } else {
+ *byte_position = 0; move16();
+ }
+ } ELSE {
+ *bit_position = add(*bit_position, 1);
+ }
+}
+
+static void array_insert_and_shift(Word32 *array, UWord8 value, Word16 longterm_analysis_counter_max, Word16 *overall_counter, Word8 *byte_position, Word8 *bit_position)
+{
+ Word32 current_byte = 0;
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PLC::array_insert_and_shift");
+#endif
+
+ IF( overall_counter != NULL)
+ {
+ *overall_counter = s_min(add(*overall_counter, 1), longterm_analysis_counter_max);
+ }
+
+ current_byte = array[*byte_position]; move16();
+ current_byte = change_bit_at_position(current_byte, *bit_position, value);
+ array[*byte_position] = current_byte; move16();
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
+#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 longterm_analysis_counter_max)
+#else
+static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 *counter_phecu, Word16 overall_counter, Word16 longterm_analysis_counter_max)
+#endif
+{
+ int i, k;
+ Word32 current_byte_tdc = 0, current_byte_ns = 0;
+ Word16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0;
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PLC::array_calculate");
+#endif
+
+ for (i = length - 1; i >= 0; i--)
+ {
+ current_byte_tdc = array_tdc[i];
+ current_byte_ns = array_ns[i];
+
+ for (k = 0; k < 30; k++)
+ {
+ counter_loc_tdc += ((current_byte_tdc >> k) & 1);
+ counter_loc_ns += ((current_byte_ns >> k) & 1);
+ counter_tmp++;
+
+ /* Break from both loops if full 2s buffer has been evaluated */
+ if (counter_tmp >= longterm_analysis_counter_max)
+ {
+ i = -1;
+ k = 30;
+ break;
+ }
+ }
+ }
+
+ *counter_tdc = counter_loc_tdc;
+ *counter_ns = counter_loc_ns;
+
+#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ *counter_phecu = sub(sub(overall_counter, counter_loc_tdc), counter_loc_ns);
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+#endif
+
+static Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length,
+ Word16 fs_idx, Word8 *scratchBuffer
+# ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+# endif
+ );
+
+void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi,
+ Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen,
+ Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer
+# ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+# endif
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 scQ15;
+ Word32 class;
+ );
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PLC::processPLCclassify_fx");
+#endif
+
+ UNUSED(yLen);
+ UNUSED(q_old_d_fx);
+
+ if (plcAd)
+ {
+ plcAd->norm_corrQ15_fx = 0; move16();
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ /* assert(bfi != 2 && "Error bfi flag value, state of fadeout cntr is affected by PartialConcealment here "); */
+ /* Save statistics for 24 kHz, 48 kHz and 96 kHz */
+ IF((sub(bfi, 1) == 0) || (((bfi >= 0) && (sub(bfi, 2) <= 0)) && ((sub(fs_idx, 2) == 0) || (sub(fs_idx, 4) == 0) || (sub(fs_idx, 5) == 0)))) /* note for PC bfi==2 is possible */
+#else
+ IF (sub(bfi, 1) == 0)
+#endif
+ {
+ /* increase counter of lost-frames-in-a-row */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ IF (sub(bfi, 1) == 0)
+ {
+ *nbLostFramesInRow = add(*nbLostFramesInRow, 1);
+ *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100);
+ }
+#else
+ *nbLostFramesInRow = add(*nbLostFramesInRow, 1);
+ *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100);
+#endif
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ /*assert((bfi != 2) && "PartialConcealment checked vs bfi==0 can cause issues "); */
+ IF ((sub(*nbLostFramesInRow, 1) == 0) || (bfi != 1) ) /* was "|| (bfi==0)" , NB only test bfi vs "1" as bfi can have the states [0(good),1(bad),2(good,partialConcealment) } */
+#else
+ IF (sub(*nbLostFramesInRow, 1) == 0)
+#endif
+ {
+ *concealMethod = plcMeth; move16();
+
+ IF(sub(plcMeth, 1) == 0)
+ {
+ IF(ltpf_mem_pitch_int > 0)
+ {
+ *concealMethod = LC3_CON_TEC_TDPLC; move16(); /* TD-PLC */
+ /* Calculate Features */
+
+ plcAd->norm_corrQ15_fx = plc_xcorr_lc_fx(plcAd->x_old_tot_fx, plcAd->max_len_pcm_plc, ltpf_mem_pitch_int, fs_idx);
+ scQ15 = spectral_centroid_fx_lc(plcAd->old_scf_q, band_offsets, bands_number, frame_length,
+ fs_idx, scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , hrmode
+#endif
+ );
+
+ /* Classify */
+ class = L_mult(plcAd->norm_corrQ15_fx, 7640);
+ class = L_mac(class, scQ15, -32768);
+ class = L_add_sat(class, -335020208);
+
+ IF(class <= 0)
+ {
+#ifdef ENABLE_HR_MODE
+ IF((frame_dms == 100) && (hrmode == 0))
+#else
+ IF(frame_dms == 100)
+#endif
+ {
+ *concealMethod = LC3_CON_TEC_PHASE_ECU; move16(); /* Phase ECU selected */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#endif
+ }
+ ELSE
+ {
+#ifndef CR9_G_PLC_NS_TDC_FIX
+ *concealMethod = LC3_CON_TEC_NS_ADV; move16(); /* Noise Substitution */
+#endif
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#endif
+ }
+ }
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ ELSE {
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ }
+#endif
+ }
+ ELSE
+ {
+ *concealMethod = LC3_CON_TEC_NS_ADV; move16(); /* Noise Substitution */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+ array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#endif
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max);
+# else
+ array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, &plcAd->longterm_counter_plcPhaseEcu, plcAd->overall_counter, plcAd->longterm_analysis_counter_max);
+# endif
+ update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
+#endif
+ }
+
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
+
+Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length,
+ Word16 fs_idx, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i, j;
+ Word32 den32, num32, tmp32;
+ Word16 s, sc, fac, freq, inv, startfreq, stopfreq;
+ Word16 s2;
+ Word16 *old_scf_q_mod;
+ Word16 *old_scf_q_mod_exp;
+ Word16 *band_offsets_local;
+ );
+#ifdef WMOPS
+ BASOP_sub_sub_start("PLC::spectral_centroid_fx_lc");
+#endif
+
+#ifdef ENABLE_HR_MODE
+ s2 = 0;
+#else
+ UNUSED(s2);
+#endif
+
+
+ old_scf_q_mod = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */
+ old_scf_q_mod_exp = (Word16 *)scratchAlign(old_scf_q_mod, sizeof(*old_scf_q_mod) * M); /* Size = 2 * M */
+ band_offsets_local = (Word16 *)scratchAlign(old_scf_q_mod_exp, sizeof(*old_scf_q_mod_exp) * (M)); /* Size = 2 * bands_number */
+
+ /* Linear Domain */
+ FOR (i = 0; i < M; i++)
+ {
+ old_scf_q_mod[i] = BASOP_Util_InvLog2_16(old_scf_q[i], &old_scf_q_mod_exp[i]);
+ }
+
+ /* De-emphasis */
+ FOR (i = 0; i < M; i++)
+ {
+ old_scf_q_mod[i] = mult(old_scf_q_mod[i], lpc_warp_dee_emphasis[fs_idx][i]); move16();
+ old_scf_q_mod_exp[i] = add(old_scf_q_mod_exp[i], lpc_warp_dee_emphasis_e[fs_idx][i]); move16();
+ }
+
+ IF (sub(bands_number, 64) == 0)
+ {
+ basop_memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(Word16));
+ }
+ IF (sub(bands_number, 32) < 0)
+ {
+ band_offsets_local[0] = 0; move16();
+ s = sub(32, bands_number);
+ FOR (i = sub(bands_number, 1); i >= s; i--)
+ {
+ band_offsets_local[(i + s) * 2 + 1 + 1] = band_offsets[i + 1]; move16();
+ band_offsets_local[(i + s) * 2 + 0 + 1] = band_offsets[i + 1]; move16();
+ }
+ FOR (i = sub(s, 1); i >= 0; i--)
+ {
+ band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1]; move16();
+ band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1]; move16();
+ band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1]; move16();
+ band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1]; move16();
+ }
+ }
+ ELSE
+ IF (sub(bands_number, 64) < 0)
+ {
+ band_offsets_local[0] = 0; move16();
+ s = sub(64, bands_number);
+ FOR (i = sub(bands_number, 1); i >= s; i--)
+ {
+ band_offsets_local[i + s + 1] = band_offsets[i + 1]; move16();
+ }
+ FOR (i = sub(s, 1); i >= 0; i--)
+ {
+ band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1]; move16();
+ band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1]; move16();
+ }
+ }
+
+ den32 = 1; move16();
+ num32 = 0; move16();
+ inv = div_s(1, frame_length);
+
+ FOR (i = 0; i < M; i++)
+ {
+ freq = 0; move16();
+ startfreq = add(band_offsets_local[i * 4], 1);
+ stopfreq = band_offsets_local[i * 4 + 4];
+
+# ifdef ENABLE_HR_MODE
+ IF (hrmode != 0)
+ {
+ tmp32 = 0; move32();
+ FOR (j = startfreq; j <= stopfreq; j++)
+ {
+ tmp32 = L_add(tmp32, j);
+ }
+
+ s2 = norm_l(tmp32);
+ freq = extract_h(L_shl(tmp32, s2));
+ s2 = sub(add(15, s2), 31);
+ tmp32 = L_mult(inv, freq);
+ s = norm_l(tmp32);
+ }
+ ELSE
+# endif
+ {
+ FOR (j = startfreq; j <= stopfreq; j++)
+ {
+ freq = add(freq, j);
+ }
+
+ tmp32 = L_mult(inv, freq);
+ s = norm_l(tmp32);
+ }
+
+ tmp32 = L_mult(old_scf_q_mod[i], extract_h(L_shl(tmp32, s)));
+
+# ifdef ENABLE_HR_MODE
+ if (hrmode != 0)
+ {
+ s = add(s, s2);
+ }
+# endif
+
+ num32 = L_add(num32, L_shl(tmp32, add(add(-15, old_scf_q_mod_exp[i]), sub(15, s))));
+ den32 = L_add(den32, L_shl(L_mult(old_scf_q_mod[i], stopfreq - startfreq + 1), old_scf_q_mod_exp[i]));
+ }
+
+ s = norm_l(den32);
+ s = sub(16, s);
+
+ sc = div_s(extract_l(L_shr(num32, s)), extract_l(L_shr(den32, s)));
+
+ SWITCH (fs_idx)
+ {
+ case 0:
+ fac = 5461; move16();
+ BREAK;
+ case 1:
+ fac = 10922; move16();
+ BREAK;
+ case 2:
+ fac = 16384; move16();
+ BREAK;
+ case 3:
+ fac = 21845; move16();
+ BREAK;
+ default: /* case 4: */
+ fac = 32767; move16();
+ BREAK;
+ }
+ sc = round_fx(L_mult(sc, fac));
+# ifdef ENABLE_HR_MODE
+ if (sub(fs_idx, 5) == 0)
+ {
+ sc = shl_pos(sc, 1);
+ }
+# endif
+
+ Dyn_Mem_Deluxe_Out();
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return sc;
+}
+
+
diff --git a/lib_lc3plus/plc_damping_scrambling_fx.c b/lib_lc3plus/plc_damping_scrambling_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c5641634867f3d803b0e10028851d98a7294e67
--- /dev/null
+++ b/lib_lc3plus/plc_damping_scrambling_fx.c
@@ -0,0 +1,430 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten,
+ Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1,
+ Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx,
+ Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms,
+ Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , UWord8 plc_fadeout_type
+#endif
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 processDampScramb;
+ );
+
+ IF ( bfi != 0 )
+ {
+ processDampScramb = 0; move16();
+ test();
+ IF (sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(bfi, 2) == 0)
+ {
+ processDampScramb = 1; move16();
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ IF (sub(ns_nbLostFramesInRow, 1) == 0)
+ {
+ *cum_fading_slow = 32767; move16();
+ *cum_fading_fast = 32767; move16();
+ *cum_fflcAtten = 32767; move16();
+ }
+#endif
+
+ IF (sub(bfi, 1) == 0)
+ {
+ processPLCDampingScrambling_fx(spec, L_spec, ns_nbLostFramesInRow, stabFac,
+ processDampScramb, cum_fflcAtten,
+ pitch_present_bfi1, frame_dms, cum_fading_slow,
+ cum_fading_fast, ns_seed, 0
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , plc_fadeout_type
+#endif
+ );
+ }
+ ELSE /* bfi == 2 */
+ {
+ processPLCDampingScrambling_fx(spec, L_spec, pc_nbLostFramesInRow, stabFac,
+ processDampScramb, cum_fflcAtten,
+ pitch_present_bfi2, frame_dms, cum_fading_slow,
+ cum_fading_fast, pc_seed, spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , plc_fadeout_type
+#endif
+ );
+
+ processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, spec, q_fx_exp, L_spec);
+ }
+ }
+ Dyn_Mem_Deluxe_Out();
+}
+
+void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb,
+ Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow,
+ Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ , UWord8 plc_fadeout_type
+#endif
+ )
+{
+ Counter i;
+ Word16 lossDuration_dms, slow, fast, tmp16;
+ Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop;
+ Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16;
+ Word32 frame_energy, mean_nrg, fac;
+ Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processPLCDampingScrambling_fx", sizeof(struct {
+ Counter i;
+ Word16 lossDuration_dms, slow, fast, tmp16;
+ Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop;
+ Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16;
+ Word32 frame_energy, mean_nrg, fac;
+ Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local;
+ }));
+#endif
+
+ /** preparation */
+#ifndef CR8_A_PLC_FADEOUT_TUNING
+ /* init cummulative damping factors at first loss */
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+ *cum_fading_slow = 32767; move16();
+ *cum_fading_fast = 32767; move16();
+ *cum_fflcAtten = 32767; move16();
+ }
+#endif
+
+ /* get damping factors */
+ tmp16 = mult(6554 /*0.2*/, stabFac);
+ slow = add(26214 /*0.8*/, tmp16);
+ fast = add( 9830 /*0.3*/, tmp16);
+
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ IF (sub(slow, 32767) < 0)
+ {
+ tmp16 = 0;
+ slow = Sqrt16_lc3plus(slow, &tmp16); move16();
+ slow = shl(slow, tmp16);
+ }
+ IF (sub(slow, 32767) < 0)
+ {
+ tmp16 = 0;
+ slow = Sqrt16_lc3plus(slow, &tmp16); move16();
+ slow = shl(slow, tmp16);
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ tmp16 = 0;
+ fast = Sqrt16_lc3plus(fast, &tmp16); move16();
+ fast = shl(fast, tmp16);
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ tmp16 = 0;
+ fast = Sqrt16_lc3plus(fast, &tmp16); move16();
+ fast = shl(fast, tmp16);
+ }
+ BREAK;
+ case 50:
+ IF (sub(slow, 32767) < 0)
+ {
+ tmp16 = 0;
+ slow = Sqrt16_lc3plus(slow, &tmp16); move16();
+ slow = shl(slow, tmp16);
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ tmp16 = 0;
+ fast = Sqrt16_lc3plus(fast, &tmp16); move16();
+ fast = shl(fast, tmp16);
+ }
+ BREAK;
+#ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ IF (sub(slow, 32767) < 0)
+ {
+ slow = mult(slow, mult(slow, slow));
+ }
+ IF (sub(slow, 32767) < 0)
+ {
+ tmp16 = 0;
+ slow = Sqrt16_lc3plus(slow, &tmp16); move16();
+ slow = shl(slow, tmp16);
+ }
+ IF (sub(slow, 32767) < 0)
+ {
+ tmp16 = 0;
+ slow = Sqrt16_lc3plus(slow, &tmp16); move16();
+ slow = shl(slow, tmp16);
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ fast = mult(fast, mult(fast, fast));
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ tmp16 = 0;
+ fast = Sqrt16_lc3plus(fast, &tmp16); move16();
+ fast = shl(fast, tmp16);
+ }
+ IF (sub(fast, 32767) < 0)
+ {
+ tmp16 = 0;
+ fast = Sqrt16_lc3plus(fast, &tmp16); move16();
+ fast = shl(fast, tmp16);
+ }
+ BREAK;
+# endif
+#endif
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if (plc_fadeout_type == 0)
+ {
+#endif
+ *cum_fading_slow = mult_r(*cum_fading_slow, slow);
+ *cum_fading_fast = mult_r(*cum_fading_fast, fast);
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ }
+#endif
+
+ IF ( sub(processDampScramb, 1) == 0 )
+ {
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if (plc_fadeout_type != 0)
+ {
+ Word16 lost_frame_thr1 = 4;
+ Word16 lost_frame_thr2 = 8;
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ lost_frame_thr1 = 16;
+ lost_frame_thr2 = 32;
+ BREAK;
+ case 50:
+ lost_frame_thr1 = 8;
+ lost_frame_thr2 = 16;
+ BREAK;
+#ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ lost_frame_thr1 = 6;
+ lost_frame_thr2 = 11;
+# endif
+#endif
+ }
+ IF (sub(nbLostFramesInRow, lost_frame_thr1) < 0)
+ {
+ cum_fading_slow_local = 32767; move16();
+ }
+ ELSE IF (sub(nbLostFramesInRow, lost_frame_thr2) < 0)
+ {
+ cum_fading_slow_local = 29491; move16();
+ }
+ ELSE
+ {
+ cum_fading_slow_local = 27852; move16();
+ }
+
+ *cum_fading_slow = mult_r(*cum_fading_slow, cum_fading_slow_local); move16();
+ cum_fading_slow_local = *cum_fading_slow; move16();
+ } else {
+#endif
+ /** rapid fading for FFLC */
+ fflcAtten = 32767; move16();
+ cum_fading_slow_local = *cum_fading_slow; move16();
+ cum_fading_fast_local = *cum_fading_fast; move16();
+
+ IF (spec_inv_idx == 0)
+ {
+ lossDuration_dms = DEPR_i_mult(nbLostFramesInRow, frame_dms);
+ IF (sub(lossDuration_dms, PLC_FADEOUT_IN_MS*10) > 0)
+ {
+ *cum_fflcAtten = 0; move16();
+ fflcAtten = 0; move16();
+ }
+ ELSE IF (sub(lossDuration_dms, 200) > 0)
+ {
+ SWITCH (frame_dms)
+ {
+ case 25: fflcAtten = PLC34_ATTEN_FAC_025_FX; BREAK;
+ case 50: fflcAtten = PLC34_ATTEN_FAC_050_FX; BREAK;
+#ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+ case 75: fflcAtten = PLC34_ATTEN_FAC_075_FX; BREAK;
+# endif
+#endif
+ case 100: fflcAtten = PLC34_ATTEN_FAC_100_FX; BREAK;
+ }
+ }
+ IF ( sub(fflcAtten, 32767) < 0 )
+ {
+ *cum_fflcAtten = mult_r(*cum_fflcAtten, fflcAtten);
+ cum_fading_slow_local = mult_r(*cum_fading_slow, *cum_fflcAtten);
+ cum_fading_fast_local = mult_r(*cum_fading_fast, *cum_fflcAtten);
+ }
+ }
+
+ /** prepare fade-out function */
+ /* being 1 up to plc_start_inFrames, being 0 starting with
+ plc_end_inFrames; decreasing linearly in between */
+ SWITCH (frame_dms)
+ {
+ case 25:
+ plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 25; move16();
+ plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 25; move16();
+ BREAK;
+ case 50:
+ plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 50; move16();
+ plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 50; move16();
+ BREAK;
+#ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 75; move16();
+ plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 75; move16();
+ BREAK;
+# endif
+#endif
+ default:
+ plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 100; move16();
+ plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 100; move16();
+ }
+
+ if (pitch_present == 0)
+ {
+ plc_start_inFrames = 1; move16();
+ }
+ plc_duration_inFrames = sub(plc_end_inFrames, plc_start_inFrames);
+
+ IF (sub(nbLostFramesInRow, plc_start_inFrames) <= 0)
+ {
+ linFuncStartStop = 32767; move16();
+ }
+ ELSE IF (sub(nbLostFramesInRow, plc_end_inFrames) >= 0)
+ {
+ linFuncStartStop = 0; move16();
+ }
+ ELSE
+ {
+ /*
+ x = xLostFramesInRow;
+ m = -1 / plc_duration_inFrames;
+ b = -plc_end_inFrames; % shift on x axis
+ linFuncStartStop = m * (x + b);
+ */
+ linFuncStartStop = div_s(sub(plc_end_inFrames, nbLostFramesInRow), plc_duration_inFrames);
+ }
+
+ /** sign scrambling */
+ randThreshold = mult(-32768, linFuncStartStop);
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ }
+#endif
+
+ tmp16 = *seed; move16();
+ FOR (i = spec_inv_idx; i < L_spec; i++)
+ {
+ tmp16 = extract_l(L_mac0(16831, tmp16, 12821));
+
+ IF (tmp16 < 0)
+ {
+ test();
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if (plc_fadeout_type != 0 || pitch_present == 0 || sub(tmp16, randThreshold) < 0 )
+#else
+ if (pitch_present == 0 || sub(tmp16, randThreshold) < 0)
+#endif
+ {
+ spec[i] = L_negate(spec[i]);
+ }
+ }
+
+ }
+ *seed = tmp16; move16();
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if (plc_fadeout_type == 0)
+ {
+#endif
+ /** adaptive damping */
+ tmp16 = mult(18022 /* 10 - 1.2 */, linFuncStartStop);
+ ad_threshFac = add(shr(tmp16, 1), 1228 /* 1.2 >> 1 */); /* exp = 5 */
+
+ s = getScaleFactor32_lc3plus(&spec[spec_inv_idx], sub(L_spec, spec_inv_idx));
+ frame_energy = 0; move32();
+ FOR (i = spec_inv_idx; i < L_spec; i++)
+ {
+ tmp16 = extract_h(L_shl_sat(spec[i], sub(s, 4)));
+ frame_energy = L_mac0(frame_energy, tmp16, tmp16); /* exp = -(2*(s-16) - 8) */
+ }
+ mean_energy16 = BASOP_Util_Divide3216_Scale_lc3plus(frame_energy, sub(L_spec, spec_inv_idx), &s2); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) */
+
+ energThreshold = mult(ad_threshFac, mean_energy16); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) + 5 */
+
+ s3 = add(sub(29, shl(sub(s, 16), 1)), s2);
+ IF (sub(energThreshold, 32767) < 0)
+ {
+ energThreshold = Sqrt16_lc3plus(energThreshold, &s3);
+ }
+ s3 = sub(s3, 15);
+
+ mean_nrg = L_shl_sat(L_deposit_l(energThreshold), s3); /* exp = 0 */
+ fac = mult(sub(cum_fading_slow_local, cum_fading_fast_local), energThreshold);
+ fac = L_shl_sat(L_deposit_l(fac), s3); /* exp = 0 */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ }
+#endif
+
+ FOR (i = spec_inv_idx; i < L_spec; i++)
+ {
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if ( ( plc_fadeout_type != 0 ) || (L_sub(L_abs(spec[i]), mean_nrg) < 0) )
+#else
+ if (L_sub(L_abs(spec[i]), mean_nrg) < 0)
+#endif
+ {
+ spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_slow_local);
+ }
+ else
+ {
+ if (spec[i] > 0)
+ {
+ spec[i] = L_add_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac);
+ }
+ else if (spec[i] == 0)
+ {
+ spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local);
+ }
+ else
+ {
+ spec[i] = L_sub_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac);
+ }
+ }
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_lpc_scaling_fx.c b/lib_lc3plus/plc_lpc_scaling_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..85ffbf9422cf3517b0535cfdf573d3c6399320c1
--- /dev/null
+++ b/lib_lc3plus/plc_lpc_scaling_fx.c
@@ -0,0 +1,36 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m)
+{
+ Counter i;
+ Word16 s;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processPLCLpcScaling_fx", sizeof(struct {
+ Counter i;
+ Word16 s;
+ }));
+#endif
+
+ s = getScaleFactor32_lc3plus(tdc_A_32, m);
+ FOR (i = 0; i < m; i++)
+ {
+ tdc_A_16[i] = round_fx_sat(L_shl_sat(tdc_A_32[i], s)); move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_main_fx.c b/lib_lc3plus/plc_main_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..1948aa23a0683361b7fac146f6c6749e2c157d1f
--- /dev/null
+++ b/lib_lc3plus/plc_main_fx.c
@@ -0,0 +1,85 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi,
+ Word16 frame_length, Word16 la_zeroes,
+#ifdef ENABLE_HR_MODE
+ const Word32 w[],
+#else
+ const Word16 w[],
+#endif
+ Word16 x_fx[], Word16 ola_mem[],
+ Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[],
+ Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping,
+ Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed,
+ AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ ,Word32 rel_pitch_change
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ ,Word16 *alpha_type_2_table
+#endif
+)
+{
+ IF(sub(bfi, 1) == 0 && plcAd)
+ {
+ /* FFLC increases the PFLC counter */
+ *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1);
+ }
+
+ processPLCclassify_fx(plcMeth, concealMethod, nbLostFramesInRow, bfi, old_pitch_int, frame_length, frame_dms,
+ fs_idx, yLen, q_old_d_fx, band_offsets, bands_number, plcAd, scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , hrmode
+#endif
+ );
+
+ processPLCapply_fx(
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ concealMethod,
+#else
+ *concealMethod,
+#endif
+ *nbLostFramesInRow, bfi, prev_bfi, frame_length, la_zeroes, w, x_fx, ola_mem,
+ ola_mem_exp, q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen, fs_idx, damping, old_pitch_int,
+ old_pitch_fr, ns_cum_alpha, ns_seed, frame_dms, plcAd, scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , hrmode
+#endif
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ , rel_pitch_change
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ , alpha_type_2_table
+#endif
+ );
+
+ IF (bfi == 0)
+ {
+ processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen);
+ }
+
+#ifdef ENABLE_HR_MODE
+ IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0) && (hrmode == 0))
+#else
+ IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0))
+#endif
+ {
+ processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx);
+ }
+
+}
+
+
diff --git a/lib_lc3plus/plc_noise_substitution_fx.c b/lib_lc3plus/plc_noise_substitution_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab618ae7e124429afc2721a496bcdb4c5419975c
--- /dev/null
+++ b/lib_lc3plus/plc_noise_substitution_fx.c
@@ -0,0 +1,32 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+
+ FOR (i = 0; i < L_spec; i++)
+ {
+ spec[i] = L_deposit_h(spec_prev[i]);
+ }
+
+ /* High pass to prevent overflows */
+ spec[0] = Mpy_32_16_lc3plus(spec[0], 6553 /* 0.2 Q15*/); move32();
+ spec[1] = Mpy_32_16_lc3plus(spec[1], 16384 /* 0.5 Q15*/); move32();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+
diff --git a/lib_lc3plus/plc_phecu_f0_refine_first_fx.c b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..5c01a00299b11d84ce760dbb71d0245f53066c1b
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c
@@ -0,0 +1,100 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void plc_phEcu_F0_refine_first_fx(Word16 * plocs, /* i/o */
+ const Word16 n_plocs_in, Word32 *L_f0est, /* i/o Q16 */
+ const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15,
+ const Word16 nSubm)
+
+{
+ Counter subm, i;
+ Word16 ploc, n_plocs_ana;
+ Word32 L_tmp = 0, L_diff, L_f0EstQ7, L_sensitivity_Q7;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_phEcu_F0_refine_first_fx", sizeof(struct {
+ Counter subm, i;
+ Word16 ploc, n_plocs_ana;
+ Word32 L_tmp, L_diff, L_f0EstQ7, L_sensitivity_Q7;
+ }));
+#endif
+
+
+
+ /* single initial peak F0 correction using available LTP information */
+
+ IF (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0)
+ {
+ ploc = -1; move16(); /* sentinel */
+ n_plocs_ana = s_min(n_plocs_in, 4); /* only analyze at first 3 deteteced LF peaks */
+
+ /* only apply analysis below nsubm*pitmax_freq ~= 1600Hz */
+ i = sub(n_plocs_ana, 1);
+ WHILE (i >= 0 && sub(plocs[i], (Word16)(1600.0 / 62.5)) > 0)
+ {
+ i--;
+ }
+ n_plocs_ana = add(i, 1);
+
+ IF ((n_plocs_ana > 0))
+ {
+ /* % find/correct first peak in f0est , that is a submultiple of n*f0Ltp*/
+ FOR (i = 0; i < n_plocs_ana; i++)
+ {
+
+ L_sensitivity_Q7 = L_deposit_l(((Word32)1) << (7 - 1)); /* 0.5 in Q7 */
+ if (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.75 * 32768.0))) < 0)
+ {
+ L_sensitivity_Q7 = L_shr_pos(L_sensitivity_Q7, 1); /* % more picky if correlation is rather low */
+ }
+
+ L_f0EstQ7 = L_shr_pos(L_f0est[i], 9); /* Q16 to Q7 */
+
+ FOR (subm = 1; subm <= nSubm; subm++)
+ {
+ /*adjf0 = abs(f0est - subm*stPhECU_f0hzLtpBin*ones(size(f0est))) < sensitivity ; % L1 difference,
+ vector operation over f0
+ ind = find(adjf0==1,1); */
+ L_diff = L_msu0(L_f0EstQ7, subm, stPhECU_f0hzLtpBinQ7);
+ L_diff = L_abs(L_diff);
+ IF (L_sub(L_diff, L_sensitivity_Q7) < 0)
+ {
+ L_tmp = L_shl_pos(L_mult0(subm, stPhECU_f0hzLtpBinQ7), 16 - 7); /* to Q16 */
+ ploc = i; move16();
+ BREAK;
+ }
+ L_sensitivity_Q7 = Mpy_32_16_lc3plus(L_sensitivity_Q7, (Word16)(0.875 * 32768.0 )); /* 2 cycles */
+ } /* subm*/
+
+ IF (ploc >= 0)
+ {
+ BREAK;
+ }
+ } /* i, n_ploc_ana*/
+ }
+
+ if (ploc >= 0)
+ {
+ L_f0est[ploc] = L_tmp; move32(); /* in Q16 */
+ /*ideally also integer plocs should be updated , e.g. if f0est goes from 1.45(plocs=1) to 1.6(plocs==2)
+ */
+ /* but that is costly and not required as long as corr_phase width is large enough ]*/
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+}
+
+
diff --git a/lib_lc3plus/plc_phecu_fec_hq_fx.c b/lib_lc3plus/plc_phecu_fec_hq_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..ca2a345f4bdae49c1a04731dddd1a0b769e6cf8a
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_fec_hq_fx.c
@@ -0,0 +1,3157 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+#include "math.h" /*dbg*/
+
+/*---------------------------------------------------------------------*
+ * Local constants
+ *---------------------------------------------------------------------*/
+
+#define DELTA_CORR 5 /* Tuning parameter - defining range for phase correction around peak */
+#define DELTA_CORR_F0_INT 2 /* Tuning parameter - defining range for phase correction around peak */
+
+#define MAX_INCREASE_GRPPOW_FX 0 /* max. amplification in case of transients (in dB scale) */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+# define ONE_SIDED_SINE_WIDTH (4) /* expected pure sine main lobe maximum width (4+1+4) bins *62.5 hz/bin => approx 560 Hz total width */
+# define SIDE_LIM 12539859L /* 10^ (4.5/20.0) = 2^(a); --> x= 0.747433821 -> Lx_Q24 = round((1L<<(24))*0.747433821)) = 12539859 */
+# define LFHF_LIM 16719812L /* 10^ (6.0/20.0) = 2^(b); --> x= 0.996578428 -> Lx_Q24 = round((1L<<(24))*0.996578428)) = 16719812 */
+#endif
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+#else
+
+#if PLC2_FADEOUT_IN_MS == 0
+#define BURST_ATT_THRESH (4) /* speech start attenuate with losses in a row , stable content is +1 */
+#define ATT_PER_FRAME 2 /* ptr to a table , regular voiced attenuation settings table [0.4 dBx16 frames + 6dBx16 frames] 10 ms frame */
+/* #define ATT_PER_FRAME 1 */ /* ptr to a table , regular attenuation settings table [0.3 dBx16 frames + 6dBx16 frames] 10 ms frame */
+#define BETA_MUTE_THR 20 /* time threshold from BFI start to start of beta-noise further energy attenuation, by .5 each frame */
+/* #define OFF_FRAMES_LIMIT 30 in defines.h , table size and complete zero signal after BURST_ATT_THRESH + OFF_FRAMES_LIMIT */
+#endif
+
+#if PLC2_FADEOUT_IN_MS != 0 /* TD_PLC muting setting */
+ /*% burst attenuation scheme is allowed to be indirectly controlled by a setting from TDC-PLC settings ,if negative PLC2_FADEOUT_IN_MS */
+
+#if (PLC2_FADEOUT_IN_MS < 0)
+#define FADEOUT_IN_MS PLC_FADEOUT_IN_MS /*% use TDC-SETTING as input */
+#else
+#define FADEOUT_IN_MS PLC2_FADEOUT_IN_MS /* % use a PLC2 individual settings as basis */
+#endif
+
+ /* %Examples
+ % FADEOUT_IN_MS ==30 ms --> shortest setting, att per frame idx = 10 for PLC2
+ % FADEOUT_IN_MS ==40 ms --> att per frame idx = 8 setting for PLC2
+ % FADEOUT_IN_MS ==60 ms --> att per frame idx = 6 setting for PLC2 (3+4) low decay then fast decay
+ % FADEOUT_IN_MS ==80 ms --> att per frame idx = 4 setting for PLC2
+ % FADEOUT_IN_MS ==100 ms --> att per frame idx = 2 longest = near original setting for PLC2
+ */
+#define PLC_P800_SPEECH_FADEOUT_IN_FRAMES (FADEOUT_IN_MS/10)
+#define PLC2_FADEOUT_IN_FRAMES MIN(OFF_FRAMES_LIMIT,MAX(6, (3*PLC_P800_SPEECH_FADEOUT_IN_FRAMES))) /* help variable */
+
+#define BURST_ATT_THRESH_PRE MIN(5,MAX(1,((1*PLC2_FADEOUT_IN_FRAMES)/6))) /* nominal 10-50 ms to start actual muting, will be thresh +1 */
+
+#undef ATT_PER_FRAME
+#define ATT_PER_FRAME MIN(10, MAX(2, 2*(6-BURST_ATT_THRESH_PRE))) /* we let the BURST_ATT_THRESH_PRE control the initial table selection */
+/* will eventually become ATT_PER_FRAME-1 = */
+ /* table ptr 1,2 --> 16 low decay, 16 high decay, "0" */
+ /* table ptr 3,4 --> 8 low decay, 24 high decay, "0" */
+ /* table ptr 5,6 --> 4 low decay, 28 high decay , "0"*/
+ /* table ptr 7,8 --> 2 low decay, 30 high decay, "0"*/
+ /* table ptr 9,10 --> 1 low decay, 31 high decay, "0"*/
+#undef BURST_ATT_THRESH
+#define BURST_ATT_THRESH MIN(BURST_ATT_THRESH_PRE, 4 ) /* nominal 10-40 ms, of no regular muting , 20-50 ms */
+
+ /* beta mute starts to become active when the low decay mute has ended */
+#undef BETA_MUTE_THR
+#define BETA_MUTE_THR MIN( 4+(OFF_FRAMES_LIMIT/2)+1 , MAX(4, BURST_ATT_THRESH + 1 +(1<<(BURST_ATT_THRESH_PRE-1)))) /* nominal time to start mandatory decrease of Xavg */
+
+#if (ATT_PER_FRAME < 2) || (ATT_PER_FRAME > 10)
+#pragma message(" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 (3), 4, (5) ,6 dB/frame ")
+#endif
+
+#else
+#if ( ATT_PER_FRAME != 2)
+#pragma (" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 dB/frame ")
+#endif
+#endif
+
+
+#endif
+
+
+#define CMPLMNT_PLOC_SENS_FX 2294 /* (1.0 - p_locator_sens) in Q15 */
+#define FEC_HQ_ECU_ROOT2 23170 /*(0x5a83) */ /* sqrt(2) in Q14 */
+#define FEC_TWOTHIRDS_Q15 21845 /* round(2^15*2/3) */
+
+static void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */
+ Word16 *ptrSin, /* Q15 */
+ Word16 *ptrCos); /* Q15 */
+
+static Word16 sqrt2ndOrder(const Word16);
+
+void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ Word32 * L_wtda_audio, /* o : tda audio Q16 20 ms */
+ const Word16 L, Word8 *scratchBuffer);
+
+static void windowing_L(const Word16 *, Word32 *, const Word16 *, const Word16, const Word16);
+static void windowing_ola(const Word16 *, Word16 *, const Word16 *, const Word16);
+static void ola_add(const Word16 *, const Word16 *, Word16 *, const Word16);
+static void intlvW32_2_flippedW16(Word32 *L_x, const Word16 numPairs, const Word16 L_prot, Word16 *x);
+static void flippedW16_2_intlvW32(Word16 *x, const Word16 numPairs, const Word16 Lprot, Word32 *L_x);
+static Word16 imax_fx(const Word16 *, const Word16);
+
+
+Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F);
+
+static Word16 imax2_jacobsen_mag_fx(const Word16 *y_re, const Word16 *y_im, const Word16 special);
+static void fft_spec2_sqrt_approx_fx(const Word16 x[], Word16 xMagSqrt[], const Word16 N);
+static Word16 sqrtMagnApprox_fx(const Word16 re, const Word16 im);
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs, const Word16 n_plocs, const Word16* X,
+ const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis pref. Max upshifted */
+ const Word16 Lprot, const Word16 fs_idx);
+#endif
+
+
+static void rotate_W16_fx(Word16 re_in, Word16 im_in, Word16 cosFactor, Word16 sinFactor, Word16 *re_out_ptr,
+ Word16 *im_out_ptr)
+{
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::rotate_W16_fx");
+#endif
+ *re_out_ptr = msu_r(L_mult(re_in, cosFactor), im_in, sinFactor); /* 2 ops no move when inlined */
+ *im_out_ptr = mac_r(L_mult(re_in, sinFactor), im_in, cosFactor); /* 2 ops no move when inlined */
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return;
+}
+
+static void valley_magnitude_adj_fx(Word16 *re_ptr, Word16 *im_ptr, Word16 uniFactor, Word16 cosFactor)
+{
+ Word16 scale_fx;
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::valley_magnitude_adj_fx");
+#endif
+
+ /* y = 0.5*((2*rand(1,10000) + 1*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */
+ /* y = 1*((1*rand(1,10000) + 0.5*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */
+
+ scale_fx /*Q15*/ = mac_r(L_mult(uniFactor, 16384), cosFactor, 16384);
+ /* make gain distribution more like N(0,1) than uniform */
+
+ scale_fx /*Q14*/ = round_fx(L_mac((Word32)(16384L << 16), scale_fx, 4096));
+ /* create a random gain scaling value with mean 1.0 and max 1.25 and min 0.75 */
+ ASSERT(scale_fx <= (16384 + 8192));
+ ASSERT(scale_fx >= (-16384 - 8192));
+ *re_ptr = mult_r(scale_fx, shl_sat(*re_ptr, 1)); /* no moves , should be inlined */
+ *im_ptr = mult_r(scale_fx, shl_sat(*im_ptr, 1)); /* no moves , should be inlined */
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return;
+}
+
+/*------------------------------------------------------------------*
+ * rand_phase()
+ *
+ * randomized phase in form of sin and cos components
+ *------------------------------------------------------------------*/
+Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F)
+{
+ /* 4x8+8 lookup scheme requiring ~40 Words of ROM freqRes 90/8 = 11.25 degrees */
+
+ /* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */
+
+ const Word16 *sincos_lowres_tab_cosQ15_fx = sincos_lowres_tab_sinQ15_fx + 8;
+ /* position at 90 degrees , ptr init */
+ Word16 seed2;
+ Word16 seed2_shift;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("rand_phase_fx", sizeof(struct {
+ const Word16 *sincos_lowres_tab_cosQ15_fx; /* position at 90 degrees */
+ Word16 seed2; /* 16 bit signed */
+ Word16 seed2_shift;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::rand_phase_fx");
+#endif
+
+ seed2 = extract_l(L_mac0(13849, seed, 31821));
+ seed2_shift = lshr(seed2, 11);
+ /* logical shift to get uniform random 5 msb bits; 0-31 , 0 degrees to 31*360/32= 348.75 */
+ *sin_F = sincos_lowres_tab_sinQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by returning seed2shift and inlining */
+ *cos_F = sincos_lowres_tab_cosQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by inlining */
+/* total WC 5 ops */
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return seed2;
+}
+
+/*-----------------------------------------------------------------------------
+ * trans_burst_ana_fx()
+ *
+ * Transient analysis
+ *----------------------------------------------------------------------------*/
+void trans_burst_ana_fx(
+ const Word16 *xfp, /* i : Input signal (, only used if time_offset==0) now in up_scaled *Q_spec */
+ Word16 * mag_chg, /* o : Magnitude modification vector Q15 */
+ Word16 * ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */
+ Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */
+ const Word16 output_frame, /* i : Frame length */
+ const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */
+ const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=Stable (==st->env_stab ) */
+ Word16 * alpha, /* o : Magnitude modification factors for fade to average */
+ Word16 * beta, /* : Magnitude modification factors for fade to average */
+ Word16 * beta_mute, /* i/o : Factor for long-term mute */
+ Word16 * Xavg, /* o : Frequency group average gain to fade to in same Q as X_sav */
+ Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx,
+ Word16 *oold_grp_shape_fx,
+
+ Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 fadeout,
+ Word32 * L_Xavg, /* full scale band amplitudes */
+#endif
+ Word8 *scratchBuffer /* Size = 4*4 * MAX_LTRANA + (2*4 + 1*2) * MAX_LGW + 8 */
+)
+{
+ Word16 att_val, attDegreeFrames;
+ Word32 * L_pGrPowLeft, *L_pGrPowRight;
+ Word32 * L_gr_pow_left, *L_gr_pow_right;
+ Word16 Lgw, i, k, burst_len;
+ Word16 man, expo;
+ Word16 att_always = 0; /* fixed attenuation per frequency group if set to 1 */
+ Word16 oneOverFrame, roundEstMusContent, tmp16;
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 burst_att_thresh;
+ Word16 att_per_frame;
+#else
+ Word16 burst_att_thresh = BURST_ATT_THRESH;
+ Word16 att_per_frame = ATT_PER_FRAME;
+#endif
+ Word16 * tr_dec;
+ Word32 L_acc;
+ Word16 fs_scale;
+ Word16 scale_sh;
+
+ Word32 L_oold_tmp, L_old_tmp;
+ Word16 oold_exp_fx, old_exp_fx;
+ Word16 margin_oold, margin_old;
+ Word16 fs_idx;
+ Word16 exp_diff;
+ Word16 Xavg_exp_fx, Xavg_mod_exp_fx;
+ Word16 tr_rise[MAX_LGW];
+ Word16 tr_decay[MAX_LGW];
+ Word16 man_in, expo_in, tmp;
+ Word32 L_tmp, L_tmp2;
+ Word16 thresh_tr_rise_lin_Q15;
+ Word16 thresh_tr_decay_lin_Q15;
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 beta_mute_thr;
+ Word16 fade_ms_ind;
+#endif
+
+#ifdef DYNMEM_COUNT
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct {
+
+ Word16 att_val, attDegreeFrames;
+ Word32 * pGrPowLeft_L, *pGrPowRight_L;
+ Word32 * L_gr_pow_left, *L_gr_pow_right;
+ Word16 Lprot;
+ Word16 Lgw, i, k, burst_len;
+ Word16 man, expo;
+ Word16 att_always; /* fixed attenuation per frequency group if set to 1 */
+ Word16 oneOverFrame, roundEstMusContent, tmp16;
+
+ Word16 burst_att_thresh;
+ Word16 att_per_frame;
+
+ Word16 * tr_dec;
+ UWord16 lsb;
+ Word32 L_acc;
+ Word16 fs_scale;
+ Word16 scale_sh;
+
+ Word32 L_oold_tmp;
+ Word32 L_old_tmp;
+ Word16 fs_idx;
+ Word16 shift32;
+ Word16 margin_old;
+ Word16 margin_oold;
+
+ Word16 Xavg_exp_fx, Xavg_mod_exp_fx;
+ Word16 tr_rise[MAX_LGW];
+ Word16 tr_decay[MAX_LGW];
+
+ Word16 man_in, expo_in, tmp;
+ Word32 L_tmp, L_tmp2;
+ Word16 thresh_tr_rise_lin_Q15;
+ Word16 thresh_tr_decay_lin_Q15;
+
+ Word16 beta_mute_thr;
+ Word16 fade_ms_ind;
+ }));
+#else
+ Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct {
+
+ Word16 att_val, attDegreeFrames;
+ Word32 * pGrPowLeft_L, *pGrPowRight_L;
+ Word32 * L_gr_pow_left, *L_gr_pow_right;
+ Word16 Lprot;
+ Word16 Lgw, i, k, burst_len;
+ Word16 man, expo;
+ Word16 att_always; /* fixed attenuation per frequency group if set to 1 */
+ Word16 oneOverFrame, roundEstMusContent, tmp16;
+
+ Word16 burst_att_thresh;
+ Word16 att_per_frame;
+
+ Word16 * tr_dec;
+ UWord16 lsb;
+ Word32 L_acc;
+ Word16 fs_scale;
+ Word16 scale_sh;
+
+ Word32 L_oold_tmp;
+ Word32 L_old_tmp;
+ Word16 fs_idx;
+ Word16 shift32;
+ Word16 margin_old;
+ Word16 margin_oold;
+
+ Word16 Xavg_exp_fx, Xavg_mod_exp_fx;
+ Word16 tr_rise[MAX_LGW];
+ Word16 tr_decay[MAX_LGW];
+ }));
+#endif
+
+#endif
+
+ UNUSED(xfp);
+ UNUSED(oold_xfp_w_E_exp_fx);
+ UNUSED(old_xfp_w_E_exp_fx);
+
+ if (time_offs == 0)
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::trans_burst_ana_fx(1st)");
+#endif
+ }
+ else
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::trans_burst_ana_fx(N)");
+#endif
+ }
+
+ fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */
+ ASSERT(fs_idx == (output_frame / 100));
+
+ L_gr_pow_left = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LGW */ /* Size = 4 * MAX_LGW */
+
+ L_gr_pow_right = (Word32 *)scratchAlign(L_gr_pow_left, sizeof(*L_gr_pow_left) * MAX_LGW); /* Size = 4 * MAX_LGW */
+
+ tr_dec = (Word16 *)scratchAlign(L_gr_pow_right, sizeof(*L_gr_pow_right) * MAX_LGW); /* Size = 2bytes * MAX_LGW */
+
+ oneOverFrame = oneOverFrameQ15Tab[fs_idx];
+ Lgw = s_min(add(fs_idx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */
+
+ burst_len = add(mult_r(time_offs, oneOverFrame), 1);
+
+ UNUSED(est_stab_content);
+ UNUSED(roundEstMusContent);
+#ifndef CR8_A_PLC_FADEOUT_TUNING
+ burst_att_thresh = add(BURST_ATT_THRESH, 1); /* in Q0 , stable setting */
+ att_per_frame = sub(ATT_PER_FRAME, 1); /* in Q0 , stable setting */
+#endif
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ move16();
+ fade_ms_ind = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /* a shorter fading entry in fade_scheme_tab_fx */
+ test();
+ if (fadeout != 0)
+ {
+ fade_ms_ind = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16();
+ /* a long fading table entry in fade_scheme_tab */
+ }
+
+ move16(); move16(); move16();
+ att_per_frame = fade_scheme_tab_fx[fade_ms_ind][0];
+ burst_att_thresh = fade_scheme_tab_fx[fade_ms_ind][1]; /* number of 1.0 frames before muting phase */
+ /* band gain muting can take place earlier due to a band transient */
+ beta_mute_thr = fade_scheme_tab_fx[fade_ms_ind][2]; /* faster muting of added noise starts when slow main signal fadeout is over */
+#endif
+
+
+
+
+#ifdef PLC_FADEOUT_IN_MS
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ ASSERT(att_per_frame >= 1 && att_per_frame <= 12); /* table based lookup restriction */
+#else
+ ASSERT(att_per_frame >= 1 && att_per_frame <=10 ); /* table based lookup restriction */
+#endif
+#else
+ ASSERT(att_per_frame == 1 || att_per_frame == 2); /* table based lookup restriction */
+#endif
+
+ *ph_dith = 0; /* peak scrambling, not in use */
+
+ attDegreeFrames = 0; move16();
+ IF(sub(burst_len, burst_att_thresh) > 0)
+ {
+ att_always = 1; move16();
+ /* increase degree of attenuation */
+
+ /* N.B. To facilitate the subsequent 10^(-att_degree/20) implementation
+ * so as to use direct table-lookup,
+ * the first (burstLen - burst_att_thresh) are NOT multiplied by "att_per_frame". */
+ attDegreeFrames = sub(burst_len, burst_att_thresh); /* multiplied by 1.0 , */
+ /* Furthermore, in order to minimize the size of the lookup-table required to
+ * implement 10^(-att_degree/10), hard limit attDegreeFrames to (30% of 100)=30.
+ * If attDegreeFrames is greater than 30, it means there are more than 30 successive
+ * bad frames. */
+ if (sub(attDegreeFrames, OFF_FRAMES_LIMIT) > 0)
+ {/* Hard limit the no. of frames, for table lookup */
+ attDegreeFrames = OFF_FRAMES_LIMIT; move16();
+ }
+ }
+
+ plc_phEcu_initWord16(alpha, 32767, MAX_LGW);
+ basop_memset(beta, 0, (MAX_LGW) * sizeof(Word16));
+ IF(sub(burst_len, 1) <= 0)
+ {
+ *beta_mute = BETA_MUTE_FAC_INI; move16();
+ *beta_mute = shr_pos(*beta_mute , 1); /* perceptual decrease */
+ }
+
+ IF(sub(burst_len, 1) <= 0)
+ {
+ L_pGrPowLeft = &L_gr_pow_left[0]; /* ptr init*/
+ L_pGrPowRight = &L_gr_pow_right[0]; /* ptr init*/
+
+ fs_scale = xfp_wE_MDCT2FFTQ11[fs_idx]; move16();
+ scale_sh = 4; /* 15-11 */ move16();
+ /* L_*old_xfp_w_E_fx, always upscaled to max from the calculating function */
+
+
+ L_oold_tmp = Mpy_32_16_lc3plus(L_oold_xfp_w_E_fx, fs_scale);
+ L_old_tmp = Mpy_32_16_lc3plus(L_old_xfp_w_E_fx, fs_scale);
+
+ oold_exp_fx = add(oold_Ltot_exp_fx, scale_sh);
+ old_exp_fx = add(old_Ltot_exp_fx, scale_sh);
+
+ /*re-normalize L_mantissas and adjust exps */
+ margin_oold = norm_l(L_oold_tmp);
+ L_oold_tmp = L_shl_pos(L_oold_tmp, margin_oold);
+ oold_exp_fx = sub(oold_exp_fx, margin_oold);
+
+ margin_old = norm_l(L_old_tmp);
+ L_old_tmp = L_shl_pos(L_old_tmp, margin_old);
+ old_exp_fx = sub(old_exp_fx, margin_old);
+
+ /* now time to analyze how the actual L_tot exponent scaling should be done */
+ /* bring up the lowest exp to the same exp as the higher exp, and scale down the corresponding mantissa */
+ exp_diff = sub(old_exp_fx, oold_exp_fx); /* energy increase from oold to old in log2 shifts */
+
+ /* Overflow2 fix */
+ exp_diff = s_max(-31, exp_diff);
+ exp_diff = s_min(31, exp_diff);
+ if (exp_diff > 0)
+ { /* oold_exp < old_exp */
+ /* old_exp is limiting, shift down oold mantissa */
+ L_oold_tmp = L_shr_pos(L_oold_tmp, exp_diff);
+ }
+ if (exp_diff < 0)
+ { /* oold_exp > old_exp */
+ /* oold_exp is limiting, shift down old mantissa */
+ L_old_tmp = L_shr_pos(L_old_tmp, negate(exp_diff));
+ }
+ oold_exp_fx = s_max(oold_exp_fx, old_exp_fx);
+ old_exp_fx = oold_exp_fx; move16();
+
+ /* safety set lowest energy to 2 , as one bit is shifted away in avg calculation */
+ L_oold_tmp = L_max(L_oold_tmp, 2L);
+ L_old_tmp = L_max(L_old_tmp, 2L);
+
+ FOR(k = 0; k < Lgw; k++) /* NB Lgw may be shorter than all defined bands , e.g at at 48k */
+ {
+ L_gr_pow_left[k] = Mpy_32_16_lc3plus(L_oold_tmp, oold_grp_shape_fx[k]); move32();
+ L_gr_pow_right[k] = Mpy_32_16_lc3plus(L_old_tmp, old_grp_shape_fx[k]); move32();
+
+ /*Xavg[k] = sqrt(0.5f*(gr_pow_left[k]+gr_pow_right[k])/(float)(gw[k+1]-gw[k]));*/
+ Xavg_exp_fx = sub(old_exp_fx, 1); /* virtual pre divide X_avg by 2 too keep precision in summation */
+ L_acc = L_add(L_shr_pos(L_gr_pow_left[k], 1), L_shr_pos(L_gr_pow_right[k], 1));
+ L_acc = L_shr_pos(L_acc, gw_len_inv_shift_fx[k]); /* divide by (bandwidth/2) in bins */
+
+ { /* new Xavg_fx calculation */
+ L_acc = L_max(L_acc, 1L);
+ tmp = norm_l(L_acc);
+ Xavg_exp_fx = sub(Xavg_exp_fx, tmp);
+ L_acc = L_shl_pos(L_acc, tmp); /* now between 0.5 an 1.0*/
+
+ expo_in = add(Xavg_exp_fx, 0);
+ man_in = round_fx_sat(L_acc);
+
+ /* now allow both positive and negative expos into sqrt */
+ man = sqrt2ndOrder(man_in);
+ if (s_and(expo_in, 1) != 0)
+ {
+ man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* 1/sqrt(2) */
+ }
+ expo = shr_r(expo_in, 1); /* apply even part of exp , square root operation. shr_r needed for positive side exps */
+
+
+
+ L_acc = L_deposit_h(man);
+ Xavg_exp_fx = add(expo, 0);
+ /*Note: sqrt approximaton may overshoot e.g- sqrt(1.0) may become 1.0001 i.e. saturation is needed when eventually applying expo */
+
+
+ /* Xavg (unscaled flt in L_acc*2^(exp-31)) needs to be saved in the same scale + Q as the stored 16bit
+ * Xsav_fx, for use in subst_spec() */
+ /* move Xavg fft scale to fx domain fx-fft scale*/
+ L_acc = Mpy_32_16_lc3plus(L_acc, PhEcu_Xsav_Flt2FxScaleQ15[fs_idx]); /* fs fixed fractional change */
+ Xavg_mod_exp_fx = sub(Xavg_exp_fx, PhEcu_Xsav_Flt2FxDnShift[fs_idx]); /* fs fixed exp change*/
+ Xavg_mod_exp_fx = add(Xavg_mod_exp_fx, Q_spec); /* signal adaptive exp change*/
+
+ /* :: move to Q_spec domain of Xsav , Q fixed in first BFI frames */
+
+ /* extract Q0 value shift so that the mantissa is in the high part with man*2,^(0-15) */
+ exp_diff = sub(15, Xavg_mod_exp_fx);
+
+
+ exp_diff = s_min(31, exp_diff); /* limit to meaningfull DSP shifts as described by up to 6 bits */
+ exp_diff = s_max(-32, exp_diff);
+ if (exp_diff > 0)
+ {
+ L_acc = L_shr_pos(L_acc, exp_diff); /* may underflow */
+ }
+
+ if (exp_diff < 0)
+ {
+ L_acc = L_shr_sat(L_acc, exp_diff);
+ }
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ L_Xavg[k] = L_acc; /* export full 31 bit scale band amplitude */
+#endif
+ Xavg[k] = round_fx_sat(L_acc); /* extract high part */
+
+ } /*end of new Xavg_fx calculation */
+ /* internal transition detection */
+
+ { /* pure percentage based transient detection */
+ thresh_tr_rise_lin_Q15 = PhEcu_frac_thr_rise_lin_Q15[k];
+ thresh_tr_decay_lin_Q15 = PhEcu_frac_thr_decay_lin_Q15[k];
+
+ /* analyse rise */
+ /* one of L_left or L_right should be pre-upshifted to a near max mantissa, (in one band ) */
+ L_tmp2 = L_deposit_h(0);
+ L_tmp = Mpy_32_16_lc3plus(*L_pGrPowRight, thresh_tr_rise_lin_Q15);
+ if (L_sub(*L_pGrPowLeft, L_tmp) <= 0)
+ {
+ L_tmp2 = L_deposit_l(1);
+ }
+
+ if (*L_pGrPowLeft == 0) /* denominator zero special cases */
+ {
+ /* rise: Right/Left ; " * / 0 " --> tr_rise=1 ; "0/0" --> tr_rise = 0 */
+ L_tmp2 = L_min(*L_pGrPowRight, 1L);
+ }
+ tr_rise[k] = extract_l(L_tmp2); move16();
+
+ /* analyse decay */
+ L_tmp2 = L_deposit_h(0);
+ L_tmp = Mpy_32_16_lc3plus(*L_pGrPowLeft, thresh_tr_decay_lin_Q15);
+ if (L_sub(L_tmp, *L_pGrPowRight) >= 0)
+ {
+ L_tmp2 = L_deposit_l(1);
+ }
+ if (*L_pGrPowRight == 0) /* right side no energy , special cases */
+ {
+ /* decay: Right/Left ; " 0 / * " --> tr_decay=0 ; "0/0" --> tr_decay = 0 */
+ L_tmp2 = L_deposit_h(0);
+ }
+ tr_decay[k] = extract_l(L_tmp2); move16();
+
+ tr_dec[k] = s_max(tr_rise[k], tr_decay[k]); move16();
+
+ } /* percentage tr_dec */
+ /* magnitude modification, calculated for decay only */
+ IF(add(tr_dec[k], att_always) != 0)
+ {
+
+#if MAX_INCREASE_GRPPOW_FX != 0
+#error trans_burst_ana_fx-- The following implementation is incorrect
+#endif
+ att_val = 32767; move16();
+ IF(L_sub(*L_pGrPowRight, 0) > 0)
+ {
+ IF(L_sub(*L_pGrPowRight, *L_pGrPowLeft) < 0) /* decay , i.e., (gr_pow_right/gr_pow_left) < 1.0 */
+ {
+ /* Compute sqrt(grp_pow_chg), where grp_pow_chg = gr_pow_right/gr_pow_left. */
+ tmp16 = plc_phEcu_ratio_fx(*L_pGrPowRight, *L_pGrPowLeft, &expo); /* output tmp16 in Q14 */
+
+ expo = sub(expo, (15 - 14)); /* Now, tmp16 is considered in Q15 */
+ i = norm_s(tmp16);
+ man = shl_pos(tmp16, i); /* Mandatory normalization before sqrtNthOrder(). */
+ expo = add(expo, i);
+ man = sqrt2ndOrder(man);
+ if (s_and(expo, 1) != 0) /* Check even or odd. */
+ {
+ man = mult_r(man, FEC_HQ_ECU_ROOT2);
+ }
+ expo = shr_pos(expo, 1); /* Divided by 2-- square root operation. */
+ att_val = shr(man, expo); /* Denormalize the mantissa back to Q15. */
+ }
+ /* ELSE
+ {
+ do nothing because (gr_pow_right/gr_pow_left) >= 1.0
+ }
+ */
+ }
+
+ mag_chg_1st[k] = att_val; move16();
+ mag_chg[k] = att_val; move16();
+ }
+ ELSE
+ {
+ mag_chg_1st[k] = 32767; move16();
+ mag_chg[k] = 32767; move16(); /* Set to ]1.0 in Q15 */
+ }
+
+ L_pGrPowLeft++;
+ L_pGrPowRight++;
+ } /* FOR band k */
+ }
+ ELSE /* sub(burst_len, 1) <= 0) */
+ {
+ /* BURST path */
+
+ /* Since attDegreeFrames is discrete (integer) and hard limited to OFF_FRAMES_LIMIT,
+ * it is easier to implement 10^(-att_degree/20.0) by a simply direct
+ * table-lookup. Also, att_per_frame is discrete as well and can be
+ * either ATT_PER_FRAME-1 or ATT_PER_FRAME and nothing else. This
+ * means only 2 tables of size=(OFF_FRAMES_LIMIT+1) each are required.
+ * To take square root into account, it is divided by 20 instead of 10. */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ if (sub(burst_len, beta_mute_thr) > 0) /* beta_mute_thr coincides/close to stronger 6dB muting phase */
+ {
+ *beta_mute = shr_pos_pos(*beta_mute, 1);
+ }
+#endif
+
+
+ FOR(k = 0; k < Lgw; k++) /* Lgw may be shorter than all bands at 48k */
+ {
+ /* global burst attenuation */
+ #if PLC2_FADEOUT_IN_MS != 0
+ #ifdef CR8_A_PLC_FADEOUT_TUNING
+ /* att_per_frame idx = "1:12") */
+#else
+ /* att_per_frame idx = "1:10") */
+#endif
+ att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16();
+#else
+ /* att_per_frame idx = "1:2") */
+ att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16();
+ /* 10^(-attDegreeFrames*(att_per_frame = "1 or 2")/20) */
+#endif
+
+ mag_chg[k] = mult_r(mag_chg_1st[k], att_val); /* Q15 */
+
+#ifndef CR8_A_PLC_FADEOUT_TUNING
+ if (sub(burst_len, BETA_MUTE_THR) > 0) /* BETA_MUTE_THR ~= (5+15) coincides/close to stronger 6dB muting phase */
+ {
+ *beta_mute = shr_pos_pos(*beta_mute, 1);
+ }
+#endif
+ alpha[k] = mag_chg[k]; move16();
+ ASSERT(beta[k] == 0); /* initialization required */
+ IF(sub(alpha[k], 32766) < 0)
+ {
+ /* beta_pre[k] = sqrt(1.0f - SQR(alpha[k])); */
+ /* beta[k] = beta_pre[k]* *beta_mute;*/
+ /* (1.0-alpha.^2), in exp 1 due to L_mult0; */
+
+ L_acc = L_sub((INT32_MAX >> 1) + 1, L_mult0(alpha[k], alpha[k]));
+ {
+
+ /* use lower complex(WMOPS/ROM) 2nd-order sqrt approximation */
+ Word32 L_man, L_acc2 = L_acc;
+ Word16 tmp, expo_in, expo2, man_in, man;
+ /* updated code using the 2nd order approximation routine */
+ /* form is flt=(L_acc2*2.^(-31 + 1) */
+
+ tmp = norm_l(L_acc2); /* tmp is always 1 or higher due to Lmac0 downshift */
+ man_in = round_fx_sat(L_shl_pos(L_acc2, tmp));
+ expo_in = sub(1, tmp); /* 1 due to original 1 bit margin gain in L_mult0 */
+
+ /* both positive and negative expos into sqrt */
+ man = sqrt2ndOrder(man_in);
+ if (s_and(expo_in, 1) != 0)
+ {
+ man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* sqrt(2)/2 */
+ }
+
+ expo2 = shr_r(expo_in, 1); /* apply square root operation. shr_r needed for pos and neg exps */
+ ASSERT(expo2 <= 1);
+
+ L_man = L_deposit_h(man);
+ L_man = L_shl_sat(L_man, expo2); /* move to a zero exp , _sat needed for 1.0 input (due to approximation overshoot) */
+
+ man = round_fx_sat(L_man); /* better perf with round here */
+
+
+ beta[k] = mult_r(*beta_mute, man); move16();
+ }
+
+ /* bw Lowpass shape additive component */
+ /* tab[LGW48K + 1] = { 1.0, ....1.0, 0.5,0.5, ... 0.1, 0.1 } */
+
+ IF(sub(k, LGW32K - 1) >= 0)
+ {
+ beta[k] = mult_r(beta[k], 3277); /* 0.1 in Q15 */
+ }
+ ELSE IF(sub(k, LGW16K - 1) >= 0)
+ {
+ beta[k] = mult_r(beta[k], 16384); /* 0.5 in Q15 */
+ }
+
+ /*
+ % limit Xavg noise contribution further in case of offset/tr_decay
+ % attenuation was already active
+
+ if (burst_len <= burst_att_thresh) && ( stPhECU_mag_chg_1st(k) < (32766/32768) )
+ XavgFadeinFactor = (burst_len-1)/burst_att_thresh;
+ XavgFadeinFactor = min(1.0, XavgFadeinFactor);
+ beta(k) = beta(k)*XavgFadeinFactor;
+ % limit initial Xavg noise contribution until We have reached regular burst attenuation
+ end
+ end
+ */
+ IF( sub(mag_chg_1st[k], 32767) <0 )
+ { /* offset muting was started before burst muting phase */
+ /* Xavg noise gradually increased during a short period */
+ Word16 XavgFadeinFactor = 32767;
+ Word16 ratio2_3_4_5tab[4][5 - 1] = {
+ {(Word16)(.5 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/2*/
+ {(Word16)(.333 * 32768.0), (Word16)(.666 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/3*/
+ {(Word16)(.25 * 32768.0), (Word16)(.5 * 32768.0), (Word16)(.75 * 32768.0), (Word16)(1.0 * 32767.0)}, /* 1/4 */
+ {(Word16)(.2 * 32768.0), (Word16)(.4 * 32768.0), (Word16)(.6 * 32768.0), (Word16)(.8 * 32768.0)} /* 1/5 */
+
+ };
+ ASSERT(burst_att_thresh >= 1 && burst_att_thresh <= 5);
+ ASSERT(burst_len >= 2);
+ if (sub(burst_len,burst_att_thresh) <= 0)
+ {
+ ASSERT(burst_len - 2 < (5-1));
+ ASSERT(burst_att_thresh-1-1 < (4));
+ XavgFadeinFactor = ratio2_3_4_5tab[burst_att_thresh-1-1][burst_len - 2]; /* second bfi frame burst_len= is 2 */
+ }
+ beta[k] = mult_r(beta[k], XavgFadeinFactor); /* n Q15 */
+ }
+ } /* IF (sub(alpha[k], 32766) < 0) */
+ } /* FOR k*/
+
+ } /* BURST */
+
+
+
+ IF(sub(output_frame, L_FRAME48K) == 0)
+ { /* for 48kHz set/handle scalings of last group/band the same way as previous lower freq band(s) */
+
+ FOR(k = Lgw; k < MAX_LGW; k++)
+ {
+ tr_dec[k] = tr_dec[k - 1]; move16(); /* only available in first bfi frame */
+ Xavg[k] = Xavg[k - 1]; move16();
+ mag_chg_1st[k] = mag_chg_1st[k - 1]; move16();
+ mag_chg[k] = mag_chg[k - 1]; move16();
+ alpha[k] = alpha[k - 1]; move16();
+ beta[k] = beta[k - 1]; move16();
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
+/*-----------------------------------------------------------------------------
+ * imax_fx()
+ *
+ * Get interpolated maximum position
+ *-----------------------------------------------------------------------------*/
+static Word16 imax_fx( /* o: The location, relative to the middle of the 3 given data point, of the maximum. (Q15) */
+ const Word16 *y, /* i: The 3 given data points. */
+ const Word16 special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */
+)
+{
+ Word16 posi;
+ Word16 man, expo, edge;
+ const Word16 *pY;
+ Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("imax_fx", sizeof(struct {
+ Word16 posi;
+ Word16 man, expo, edge;
+ const Word16 *pY;
+ Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::imax_fx");
+#endif
+
+ /* Seek the extremum of the parabola P(x) defined by 3 consecutive points
+ so that P([-1 0 1]) = [y1 y2 y3] */
+ pY = y;
+ L_y1 = L_deposit_l(*pY++), L_y2 = L_deposit_l(*pY++), L_y3 = L_deposit_l(*pY);
+
+ /* The extremum value:
+ * y2i = -0.125f * SQR(y3_y1) / (y1+y3-2*y2)+y2
+ * is not computed. Alternatively, the derivative of the parabola evaluated at y=0,
+ * dP/dy|y=0, is used to determine whether the extremum is maximum or not.
+ */
+
+ /* Compute the extremum location: posi = (y3 - y1)/(4*y2 - 2*y1 - 2*y3). */
+ L_y3_y1 = L_sub(L_y3, L_y1);
+ L_acc = L_shl_pos(L_y2, 1); /* N.B. y2 is multiplied by 2 not 4. */
+ L_acc = L_sub(L_acc, L_y1); /* N.B. Y1 is not multiplied by 2. */
+ L_denom = L_sub(L_acc, L_y3); /* N.B. Y3 is not multiplied by 2. */
+ L_sign = L_xor(L_y3_y1, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */
+ L_numer = L_abs(L_y3_y1);
+ L_denom = L_abs(L_denom);
+
+ test();
+ IF(L_numer == 0 || L_denom == 0)
+ {
+ posi = 0; move16(); /* flat top , exit with center freq. */
+ }
+ ELSE
+ {
+
+ IF(L_sub(L_denom, L_shr_pos_pos(L_numer, 1)) > 0)
+ {
+ /* Although the output of ratio() is in Q14, adding the missing factor of 2 (See above)
+ * in the denominator, the output is now considered to be in Q15. */
+ man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */
+
+ posi = shr_sat(man, expo); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */
+ }
+ ELSE
+ {
+ posi = 0x7fff; move16();
+ }
+
+ if (L_sign < 0) /* Restore the sign. */
+ {
+ posi = negate(posi);
+ }
+
+ /* For both edges (left and right), the extremum found above may be minimum.
+ * It needs to reject the minimum. */
+ IF(special != 0) /* Either edge special case. */
+ {
+ edge = 0x7fff; /* 1 in Q15 for the right edge special case */ move16();
+ if (special < 0)
+ {
+ edge = 0; /* Left edge special case */ move16();
+ }
+
+ /* The derivative (slope) of the interpolating parabola = 2*A*y + B,
+ * where A = (y3 + y1)/2 - y2
+ * and B = (y3 - y1)/2.
+ * Therefore, the slope at y=0 is simply B. Use this slope to determine
+ * if the parabola is concave upward or downward.
+ */
+ IF(posi > 0) /* The extremum is in between the middle and the right given data points. */
+ {
+ posi = sub(0x7fff, posi); /* maximum case */
+ if (L_sub(L_y3, L_y1) <= 0) /* Check the slope at y=0, i.e., at the middle given data point. */
+ {
+ posi = edge; /* minimum case */ move16();
+ }
+ }
+ ELSE /* The extremum is in between the left and the middle given data points. */
+ {
+ posi = add(0x7fff, posi); /* maximum case */
+ if (L_sub(L_y3, L_y1) >= 0)
+ {
+ posi = edge; /* minimum case */ move16();
+ }
+ }
+ }
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return posi;
+ /* Q15. The position either left or right relative to the index of the middle of the 3 given data points. */
+}
+
+ /*-----------------------------------------------------------------------------
+ * spec_ana_fx()
+ *
+ * Spectral analysis
+ *-----------------------------------------------------------------------------*/
+ /* OPT add the FB transient input flags , and skip peakfinder if fullband transient is set */
+ void spec_ana_fx(Word16 * xfp, /* i/o : Input 16ms pre-upscaled time signal, output xfp utility buffer */
+ Word16 * plocs, /* o : The indicies of the identified peaks Q0 */
+ Word32 * L_plocsi, /* o : Interpolated positions of the identified peaks Q16 */
+ Word16 * num_plocs, /* o : Number of identified peaks Q0 */
+ Word16 * X_sav, /* o : Stored fft spectrum */
+ const Word16 output_frame, /* i : Frame length Q0 */
+ const Word16 bwidth_fx, /* i : Encoded Fs index Q0 */
+ const Word16 *sp_ana_win, /* i : spectral analysis window Q15 */
+ const Word16 f0hzLtpBinQ7, /* i : LTP bin frequency in normalized Hz Q7 */
+ const Word16 norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */
+ Word16 maxLprot, Word16 maxPlocs,
+ Word8 *scratchBuffer /* Size = 4 * (MAX_LPROT + MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */
+ )
+ {
+ Counter n, k;
+ Word16 nJacob, Lprot, hamm_len2 = 0, Lprot2, Lprot2p1;
+ Word32 *L_xfp;
+
+ Word16 *pXfp;
+ Word16 *pPlocs;
+ Word16 Xmax, Xmin, sens;
+ Word16 rectLength, fraction;
+ Word32 *pPlocsi_L;
+ Word32 L_acc;
+ Word16 peak_range_1;
+ Word16 stop_band_start;
+ Word16 stop_band_length;
+ Word16 fft_scale;
+ Word8 * buffer_fft;
+ Word16 currPlocs, endPlocs;
+ Word16 P_in_plocs;
+ Word16 n_real_interp_tail;
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::spec_ana_fx(1st)");
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("spec_ana_fx", sizeof(struct {
+ Counter n, k;
+ Word16 nJacob ,Lprot, hamm_len2, Lprot2, Lprot2p1;
+ Word32 *L_xfp;
+ Word32 *pXfp_L;
+ Word16 *y_re_ptr, *y_im_ptr; /* otrs to Xsav as xfp was overwritten */
+ Word16 *pXfp, *pXfp1, *pPlocs;
+ Word16 Xmax, Xmin, sel;
+ Word16 rectLength, fraction, special;
+ Word32 *pPlocsi_L;
+ Word32 L_acc;
+ Word16 peak_range_1;
+ Word16 stop_band_start;
+ Word16 stop_band_length;
+ Word16 fft_scale;
+ Word8 * buffer_fft;
+ Word16 fft_scale_by4;
+ Word16 currPlocs, endPlocs;
+ Word16 P_in_plocs;
+ Word16 n_real_interp_tail;
+ }));
+#endif
+ /* Initialize for 48k to avoid warnings
+ Lprot - length of saved prototype samples
+ hamm_len2 - half Hamming window length
+ pFftTbl - Table for real input FFT
+ LprotLog2Minus1 - FFT stages for complex input FFT
+ */
+
+
+ L_xfp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT bytes */
+ buffer_fft = scratchAlign(L_xfp, sizeof(*L_xfp) * maxLprot); /* Size = 4 * (MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */
+
+ ASSERT(bwidth_fx >= 0 && bwidth_fx <= 4); /* avoid bwidth_fx variable warning */
+
+ Lprot = LprotSzPtr[bwidth_fx];
+ move16();
+ hamm_len2 = DEPR_i_mult(3, mult(output_frame, (Word16)(3277) /* divBy10 + floor */)); /* 3 ms */
+ fft_scale = PhEcuFftScale[bwidth_fx];
+ move16(); /* 32,16,8 kHz all have fft scale 0, 24 has 8, 48 has 4 */
+ Lprot2 = shr_pos(Lprot, 1);
+ Lprot2p1 = add(Lprot2, 1); /* Magnitude lengths */
+ rectLength = sub(Lprot, shl_pos(hamm_len2, 1));
+ /* The length of the rectangular portion of the Hamming-Rectangular window. */
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::WhrAnaWin+fft");
+#endif
+
+ /* Apply hamming-rect window */
+ windowing_L(xfp, L_xfp, sp_ana_win, rectLength, hamm_len2);
+ BASOP_rfftN(L_xfp, Lprot, &fft_scale, buffer_fft);
+ }
+#ifdef WMOPS
+ BASOP_sub_sub_end(); /* anawin+fft */
+#endif
+
+ /* Convert 32 Bit intlv FFT into phecu 16 bit flipped fft format */
+ /* can not yet be an inplace operation */
+
+ intlvW32_2_flippedW16(L_xfp, sub(Lprot2, 1), Lprot, xfp);
+
+ /* Apply zeroing of non-coded FFT spectrum above 20 kHz */
+ IF(sub(output_frame, ((L_FRAME48K) * 40) / 48) >= 0) /* only relevant for 48kHz in LC3plus */
+ {
+ stop_band_start = ((LPROT48K / 2) * 40) / 48; /* initial start position in real part , 320 */
+ stop_band_length = ((LPROT48K * 8) / 48) - 1; /* real tail and into Im parts , 128-1 */
+ stop_band_start = add(stop_band_start, 1); /* exclude DC ... */
+
+ basop_memset(xfp + stop_band_start, 0, (stop_band_length) * sizeof(Word16));
+ }
+
+ peak_range_1 = s_min(Lprot2p1, MAX_LPROT_RED / 2 + 1); /* limit preliminary only active for 48k to save WMOPS */
+
+ basop_memmove(X_sav, xfp, (Lprot) * sizeof(Word16));
+
+ /* Magnitude representation */
+ fft_spec2_sqrt_approx_fx(xfp, xfp, Lprot);
+ /* inplace, i.e. [ Dc, real part of xfp ,Fs/2 ] will be replaced by magnitude(scaled by .5) */
+
+ /* Find global maximum and minimum. */
+ plc_phEcu_maxval_fx(xfp, peak_range_1, &Xmax);
+ plc_phEcu_minval_fx(xfp, peak_range_1, &Xmin);
+ sens = mult_r(sub(Xmax, Xmin), CMPLMNT_PLOC_SENS_FX);
+
+
+ plc_phEcu_peak_locator_fx(xfp, peak_range_1, plocs, num_plocs, sens, Xmax, Xmin, MAX_LPROT_RED, buffer_fft);
+
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::Peaks_refine");
+#endif
+
+ /* Refine peaks */
+ pPlocsi_L = L_plocsi;
+ pPlocs = plocs;
+ /* n = sub(*num_plocs, 1); */ /* -1 so as to exclude the very last peak. */
+ n = *num_plocs; /* number of peaks to process */
+ /* Special case-- The very 1st peak if it is at 0 index position (DC) */
+ /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */
+ logic16();
+ IF((n > 0) && (sub(*pPlocs, 0) == 0)) /* Very 1st peak position possible to have a peak at 0/DC index position. */
+ {
+ fraction = imax_fx(xfp, -1); /* -1 signifies special left edge case. */
+ L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be zero here. */
+ *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */
+ n = sub(n, 1); /* This special case is taken care of -- one less peak to go */
+ }
+ logic16();
+ IF((n > 0) && (sub(*pPlocs, 1) == 0)) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */
+ {
+ fraction = imax_fx(xfp, 0); /* for parabolic this is not a special case. */
+ L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be 1 here. */
+ *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */
+ n = sub(n, 1); /* This special case is taken care of -- one less peak to go */
+ }
+
+ /* All remaining peaks except the very last two possible integer positions */
+ currPlocs = *pPlocs++; move16();
+ endPlocs = sub(Lprot2p1, DELTA_CORR_F0_INT); /* last *pPlocs position for Jacobsen */
+
+ /* precompute number of turns based on endpoint integer location and make into a proper FOR loop */
+ IF(n > 0)
+ {
+ nJacob = n; move16();
+
+ /* catch all three xxx01 , xxx10 and xxx11 ,
+ and not only xxx01, xxx10 */
+
+ n_real_interp_tail = 0; move16();
+ if (sub(endPlocs, plocs[sub(*num_plocs, 1)]) <= 0)
+ {
+ n_real_interp_tail = add(n_real_interp_tail, 1);
+ }
+
+ logic16();
+ if (sub(n,1) > 0 && sub(endPlocs, plocs[sub(*num_plocs, 2)]) <= 0)
+ {
+ n_real_interp_tail = add(n_real_interp_tail, 1);
+ }
+
+ nJacob = sub(nJacob, n_real_interp_tail);
+
+ FOR (k = 0; k < nJacob; k++)
+ {
+ fraction = imax2_jacobsen_mag_fx(&(X_sav[currPlocs - 1]), &(X_sav[Lprot - 1 - currPlocs]), 0); /* in Q15 */ /* not endpoint */
+ move16(); move16(); /* account for inloop indirect ptrs into Xsav */
+
+ L_acc = L_deposit_h(currPlocs);
+ *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16. Append the fractional part to the integral part. */
+ currPlocs = *pPlocs++; move16();
+ }
+ n = sub(n, nJacob);
+ }
+
+ /* At this point there should at most two plocs left to process */
+ /* the position before fs/2 and fs/2 both use the same magnitude points */
+
+ IF(n > 0)
+ {
+ /* [ . . . . . . . ] Lprot/2+1 positions */
+ /* | | | */
+ /* 0 (Lprot/2-2) (Lprot/2) */
+
+ pXfp = xfp + sub(Lprot2, 2);
+ IF(sub(currPlocs, sub(Lprot2p1, DELTA_CORR_F0_INT)) == 0)
+ /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */
+ {
+ fraction = imax_fx(pXfp, 0); /* for parabolic this is not a special case. */
+
+ L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */
+ *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */
+ currPlocs = *pPlocs++; move16();
+ n = sub(n, 1); /* This special case is taken care of -- one less peak to go */
+
+ if (n > 0)
+ {
+ /* allow for an additional consecutive final plocs after (Fs/2-1) at Fs/2 */
+ currPlocs = *pPlocs++; move16();
+ }
+ }
+
+ /* Here the only remaining point would be a fs/2 plocs */
+ /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it whould point */
+ IF(n > 0) /* fs/2 which makes special case . */
+ {
+ fraction = imax_fx(pXfp, 1); /* for parabolic this is a special case. */
+
+ L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */
+ *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */
+ currPlocs = *pPlocs++; move16();
+ n = sub(n, 1); /* This special case is taken care of -- one less peak to go */
+ }
+ }
+
+ /* here n should be 0 if all peaks have been processed */
+ ASSERT(n == 0);
+
+ /* Check number of plocs within an assumed pitch range */
+ P_in_plocs = 0; move16();
+ FOR(n = 0; n < *num_plocs; n++)
+ {
+ /* count number of peaks in locations 1,2,3,4,5,6 , ~= 60 Hz ... 380 Hz */
+ fraction = s_min(1, plocs[n]); /* 0 stays zero , otherwise 1 */
+ if (sub(plocs[n], 7) < 0)
+ {
+ P_in_plocs = add(P_in_plocs, fraction);
+ }
+ }
+
+#ifdef WMOPS
+ BASOP_sub_sub_end(); /* peaks refine */
+#endif
+
+ logic16();
+ IF(f0hzLtpBinQ7 > 0 && P_in_plocs > 0)
+ {
+ Word16 n_plocs_in, n_plocs_out;
+
+ n_plocs_in = *num_plocs; move16();
+
+ /* NB LF peak analysis may add adjacent peaks in { plocs, L_plocsi}, (output from peakfinder did not have
+ * adjacent peaks ) */
+ plc_phEcu_LF_peak_analysis_fx(plocs /* i/o */, num_plocs /* i/o */, L_plocsi /* i/o */, xfp, f0hzLtpBinQ7,
+ norm_corrQ15_fx, 2, maxPlocs, buffer_fft);
+ n_plocs_out = *num_plocs; move16();
+
+ IF(sub(n_plocs_in, n_plocs_out) == 0)
+ {
+ /* adjust first peak coinciding with LTPF0 measures if it indicates so */
+ plc_phEcu_F0_refine_first_fx(plocs /* i/o */, *num_plocs, L_plocsi /* i/o */, f0hzLtpBinQ7, norm_corrQ15_fx,
+ 3);
+ }
+ }
+ /* moved inside spec_ana_fx , to include validated pitch peak P_in_plocs*/
+ {
+ Word16 peak_limits_fx[5] = { 14 /*NB*/, 14 /*WB*/, 14 /*sWB*/, 14 /*SWB*/,
+ 14 /* FB */ }; /* to be trained for each BW */
+
+ test();
+ test();
+ IF((sub(norm_corrQ15_fx, 0) > 0) && /* == 0 indicates a negative correlation, which could be likely stable */
+ (sub((Word16)(0.5 * 32768), norm_corrQ15_fx) > 0) && (sub(*num_plocs, peak_limits_fx[bwidth_fx]) > 0))
+ {
+ if (P_in_plocs > 0)
+ {
+ *num_plocs = 0; move16(); /*activate noise only path only if normcorr vas valid energywise */
+ }
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ /*-------------------------------------------------------------------*
+ * subst_spec_fx()
+ *
+ * Substitution spectrum calculation
+ *-------------------------------------------------------------------*/
+
+ void subst_spec_fx(
+ const Word16 *plocs, /* i : The indices of the identified peaks Q0 */
+ const Word32 *L_plocsi, /* i : Interpolated positions of the identified peaks Q16 */
+ Word16 * num_plocs, /* i/o : Number of identified peaks Q0 */
+ const Word16 time_offs, /* i : Time offset Q0 */
+ Word16 * X, /* i/o : FFT spectrum */
+ const Word16 *mag_chg, /* i : Magnitude modification Q15 */
+ const Word16 ph_dith, /* i : Phase dither, 2*PI is not included. (Q15, i.e., between 0.0 and 1.0) */
+ const Word16 *is_trans, /* i : (Transient) noise generation flags (either 0 or not 1 ) */
+ const Word16 output_frame, /* i : Frame length Q0 */
+ Word16 * seed, /* i/o : Random seed */
+ const Word16 *alpha, /* i : Magnitude modification factors for fade to average Q15 */
+ const Word16 *beta, /* i : Magnitude modification factors for fade to average Q15 */
+ const Word16 *Xavg, /* i : Frequency group averages to fade to Q0 */
+ const Word16 t_adv /* i : time adjustement excluding time_offs Q0 */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ ,const Word16 fadeout, /* need for DC muting */
+ Word16 * nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */
+ const Word32 * L_Xavg /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */
+#endif
+ )
+ {
+ Word16 Xph_short;
+ Word32 L_corr_phase[MAX_PLOCS], L_Xph;
+ Word32 *pCorrPhase_L;
+ Word16 cos_F, sin_F, tmp;
+ Word16 peak_sin_F = 0, peak_cos_F = 0;
+ Word16 sin_F_fade2avg, cos_F_fade2avg;
+ Word16 fs_idx;
+ Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp;
+ UWord16 lsb;
+ Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen;
+ Word16 pkLocation_1, pkLocation, pkLocation1;
+ const Word16 *pPlocs;
+ const Word32 *pPlocsi_L;
+ Word32 L_acc;
+ Word16 Lprot_inv;
+ Word16 k;
+ Word16 tmp2;
+ Word16 alpha_local;
+ Word32 tmp_L;
+ Word16 mag_chg_local;
+ const Word16 *gwlpr_fxPlus1;
+ Word16 one_peak_flag_mask;
+ Word16 noise_mag_scale_neg;
+ Word16 up_shift_adj;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("subst_spec_fx", sizeof(struct {
+ Word16 Xph_short;
+ Word32 L_corr_phase[MAX_PLOCS], L_Xph;
+ Word32 *pCorrPhase_L;
+ Word16 cos_F, sin_F, tmp;
+ Word16 peak_sin_F, peak_cos_F;
+ Word16 sin_F_fade2avg, cos_F_fade2avg;
+ Word16 fs_idx;
+ Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp;
+ UWord16 lsb;
+ Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen;
+ Word16 pkLocation_1, pkLocation, pkLocation1;
+ const Word16 *pPlocs;
+ const Word32 *pPlocsi_L;
+ Word32 L_acc;
+ Word16 Lprot_inv;
+ Word16 k;
+ Word16 tmp2;
+ Word16 alpha_local;
+ Word16 expo;
+ Word32 tmp_L;
+ Word16 mag_chg_local;
+ const Word16 *gwlpr_fxPlus1;
+ Word16 one_peak_flag_mask;
+ Word16 noise_mag_scale_neg;
+ Word16 up_shift_adj;
+ }));
+#endif
+
+ if (time_offs == 0)
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::subst_spec_fx(1st)");
+#endif
+ }
+ else
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::subst_spec_fx(N)");
+#endif
+ }
+
+
+ gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */
+ fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */
+ ASSERT(fs_idx == (output_frame / 100));
+ Lprot = LprotSzPtr[fs_idx];move16();
+ Lprot_inv = InvLprot_Q22[fs_idx]; move16();
+
+ tmp2 = add(mult_r(time_offs, oneOverFrameQ15Tab[fs_idx]), 1);/* save a local burst_len for securing DC and fs/2 muting */
+
+ /* Correction/evolution phase of the identified peaks */
+ IF(s_or(is_trans[0], is_trans[1]) != 0)
+ {
+ *num_plocs = 0; move16();
+ }
+ ELSE
+ {
+
+ tmp = t_adv;
+
+ tmp = add_sat(tmp, time_offs);
+ /* NB tmp can be stored in Word16 Q0 as max used value is 684+(OFF FRAMELIMIT==60)*480 = 29484 */
+ tmp_L = L_mult0(tmp, Lprot_inv);
+
+
+ tmp = norm_l(tmp_L);
+ up_shift_adj = s_max(0, sub(4, tmp)); /* 48kHz : PLC frame 1..49 -> tmp_L<<4 , frame 50..60 -> tmpL<<3 */
+ tmp_L = L_shl_sat(tmp_L, sub(4, up_shift_adj));
+ tmp = round_fx_sat( tmp_L);
+
+
+ pPlocsi_L = L_plocsi;
+ pCorrPhase_L = L_corr_phase;
+ FOR(m = 0; m < *num_plocs; m++)
+ {
+
+ /* tmp has variable resolution 10 or 9 bits */
+ ASSERT( up_shift_adj >= 0);
+ Mpy_32_16_ss(L_shl_pos(*pPlocsi_L++, up_shift_adj), tmp, &L_acc, &lsb);
+ L_acc = L_add(L_shl_pos(L_acc, 5), lshr(lsb, 11));
+ /* 5 lsb's actually unused though, as 6 bits are shifted out */
+ *pCorrPhase_L++ = L_acc; move32();/* in Q16. 2*PI is not included. */
+ }
+ }
+
+ one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ test(); logic16();
+ IF((*num_plocs > 0) && sub(*num_plocs, 3) < 0)
+ {
+ one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zeroes in valleys, single clean tone assumed */
+
+ /* revert initial pure tone decision in some cases */
+ logic16(); logic16();
+ IF((sub(*nonpure_tone_flag_ptr, 0) < 0) &&
+ ((sub(fs_idx, 2) == 0)/* SemiSWB 24 kHz */ || (sub(fs_idx, 4) >= 0)) /* FB 48 kHz */
+ )
+ {
+ /* in the first lost frame analyze spectra and spectral bands to possibly reverse an initial pure sine assumption */
+ *nonpure_tone_flag_ptr = plc_phEcu_nonpure_tone_ana_fx(plocs, *num_plocs, X, L_Xavg, Lprot, fs_idx);
+
+#ifdef LOCAL_PLC2_TON_ANA_DEACTIVATE
+ *nonpure_tone_flag_ptr = 0; /* dbg of inactive tone analysis */
+#endif
+ }
+
+
+ if (sub(*nonpure_tone_flag_ptr, 0) > 0)
+ {
+ /* actually revert single pure tone detection */ /* 0-> mute all surrounding valley bins in evolution , 0xff -> generate noise in all valleys */
+ one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */
+ }
+ }
+#else
+ logic16();
+ if ((*num_plocs > 0) && sub(*num_plocs, 3) < 0)
+ {
+ one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zero */
+ }
+#endif
+
+
+ noise_mag_scale_neg = 0; move16(); /* no change of valley noise magnitude */
+ logic16();
+ if ((*num_plocs == 0) || (time_offs != 0))
+ { /* only adj_scale noise amplitude when we have no WC path , or in all noise frame */
+ noise_mag_scale_neg = -32768; move16(); /* all ones --> scale_noise */
+ }
+
+ IF(*num_plocs == 0)
+ {
+ X[0] = 0; move16(); /* reset DC if there are no peaks */
+ X[shr_pos(Lprot, 1)] = 0; move16(); /* also reset fs/2 if there are no peaks */
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ /* the binary selection of fadeout scheme */
+ tmp = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16();
+ if (fadeout != 0)
+ {
+ tmp = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16();
+ }
+
+ IF(sub(tmp2, add(fade_scheme_tab_fx[tmp][1],1) ) > 0)
+#else
+ IF(sub(tmp2, (BURST_ATT_THRESH+1)) > 0)
+#endif
+ {
+ /* also start DC scaling attenuation */
+ X[0] = mult(alpha[0], X[0]); move16();
+ /* start fs/by2 attenuation */
+ X[shr_pos(Lprot, 1)] = mult(alpha[s_min(add(fs_idx, LGW8K), LGW48K)], X[shr_pos(Lprot, 1)]); move16();
+ }
+
+
+ lprotBy2Minus1 = sub(shr_pos(Lprot, 1), 1);
+
+ /* for 48k the last (63+1+63) 128/2-1 values above 20 kHz are always zeroes */
+ { /* after a last, peak no need to evolve above 20kHz , those coeffs have been/ will be zeroed already */
+ /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */
+ /*N: 1, 320 , 63 , 1 , 63 , 320 */
+ /*Cind: 0, 1-320, 321-383 , 384 , 385-447, 448 -767 */
+ lprotBy2Minus1 = s_min( lprotBy2Minus1, 320);
+ /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be zeroed */
+ }
+
+ i = 1; move16(); /* index in the X[DC, ReX part of X_Sav ,i.e *pReX == X[i] */
+ k = 0; move16();
+
+ pReX = X + i;
+ im_ind = (Lprot - 1); /* ptr init */
+ pImX = X + im_ind;
+ pPlocs = plocs;
+ pCorrPhase_L = L_corr_phase;
+
+
+ pkLocation_1 = -4; move16(); /* dummy value to avoid Out of Array Read */
+ pkLocation = -3; move16(); /* dummy value to avoid Out of Array Read for the *num_plocs==0 case */
+ pkLocation1 = -2; move16(); /* dummy value to avoid Out of Array Read */
+
+ IF (*num_plocs != 0)
+ {
+
+ pkLocation = *pPlocs; move16(); /* N.B. No post-increment */
+ lastPeak = sub(*num_plocs, 1);
+ if (lastPeak >= 0)
+ {
+ pkLocation1 = *pPlocs++; move16(); /* get a next peak */
+ }
+ }
+
+ FOR(m = 0; m < *num_plocs; m++)
+ {
+ pkLocation_1 = pkLocation; /* plocs[m - 1] */ move16();
+ pkLocation = pkLocation1; /* plocs[m] */move16();
+
+ /*location dependent update of plocs[m + 1] */
+ if ( sub(lastPeak, m) > 0)
+ { /* only read additional peak when teher is a valid position to read */
+ pkLocation1 = *pPlocs++; /* plocs[m + 1] */ move16();
+ }
+
+ delta_tmp = shr_pos(sub(sub(pkLocation, pkLocation_1), 1), 1);
+ if (m == 0)
+ {
+ delta_tmp = DELTA_CORR; move16(); /* first peak special case */
+ }
+ delta_corr_dn = s_min(delta_tmp, DELTA_CORR);
+
+ delta_tmp = shr_pos(sub(sub(pkLocation1, pkLocation), 1), 1);
+ if (sub(m, lastPeak) >= 0)
+ {
+ delta_tmp = DELTA_CORR; move16();
+ }
+ delta_corr_up = s_min(delta_tmp, DELTA_CORR); /* last peak special case */
+
+
+ /* Input Xph */
+ segmentLen = sub(sub(pkLocation, delta_corr_dn), i); /* may be negative */
+
+ ASSERT(pReX == &(X[i]));
+ ASSERT(*pReX == X[i]); /*before first, nth valley*/
+
+ FOR(j = 0; j < segmentLen; j++) /* valley section , may be skipped for segmentlen < 0 */
+ {
+
+ *seed = rand_phase_fx(*seed, &sin_F, &cos_F);
+
+ /* phase scrambling */
+ rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* tmp=real part, should be inlined */
+ UNUSED(re);
+
+ /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */
+ *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg);
+ IF(noise_mag_scale_neg != 0)
+ {
+ valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F);
+ /* use two random variables */ /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg
+ */
+ }
+
+ IF( beta[k] != 0 )
+ {
+ alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */
+ /* the fade2avg mixing branch, fade2avg and transient downscaling and evolution rotation */
+ tmp2 = mult_r(beta[k], Xavg[k]);
+
+ {
+ tmp2 = s_and(tmp2, one_peak_flag_mask);
+ tmp = s_and(tmp, one_peak_flag_mask);
+ im = s_and(im, one_peak_flag_mask);
+ }
+
+ *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16();
+ *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16();
+ }
+ ELSE
+ { /* the no fade2avg mixing branch, only transient downscaling and evolution rotation */
+ {
+ tmp = s_and(tmp, one_peak_flag_mask);
+ im = s_and(im, one_peak_flag_mask);
+ }
+
+
+ *pReX++ = mult_r(mag_chg[k], tmp); move16();
+ *pImX-- = mult_r(mag_chg[k], im); move16();
+ }
+ i = add(i, 1);
+ ASSERT(pReX == &(X[i])); /* nth Valley */
+ ASSERT(*pReX == X[i]); /* nth Valley */
+ if (sub(i, gwlpr_fxPlus1[k]) >= 0)
+ {
+ k = add(k, 1);
+ }
+ } /* segment_len 1st++ etc valley excluding last */
+
+ /* peak area section */
+
+ e = s_min(lprotBy2Minus1, add(pkLocation, delta_corr_up));
+ segmentLen = sub(e, sub(i, 1));
+
+
+ L_Xph = *pCorrPhase_L; move32();
+ /* rounding here, add "0.5" before extracting the 10 bits for table lookup */
+ Xph_short = s_and(extract_l(L_shr_pos_pos(L_add(L_Xph, (1L << (16 - 10 - 1))), 16 - 10)), 0x3ff);
+ /* 10 bits precision after radix point, for a virtual 0-1023 sin/cos table lookup */
+
+
+ get_sin_cosQ10opt(Xph_short, &peak_sin_F, &peak_cos_F);
+
+
+ ASSERT(pReX == &(X[i])); /*before peak*/
+ FOR(j = 0; j < segmentLen; j++)
+ {
+ mag_chg_local = mag_chg[k]; /* mag_chg_local actually only need for debugging , no move16()*/
+
+ UNUSED(ph_dith);
+ *seed = extract_l(L_mac0(13849, *seed, 31821));
+ rotate_W16_fx(*pReX, *pImX, peak_cos_F, peak_sin_F, &tmp, &im); /* should be inlined */
+ UNUSED(re);
+
+ *seed = rand_phase_fx(*seed, &sin_F, &cos_F);
+
+ IF( beta[k] != 0 )
+ { /* fade2avg path alpha*X_sav + beta *Xavg */
+ alpha_local = mag_chg_local; /* no move alpha_local only needed for dbg */
+ tmp2 = mult_r(beta[k], Xavg[k]);
+
+
+ *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F); move16();
+ *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F); move16();
+ }
+ ELSE
+ {
+ *pReX++ = mult_r(mag_chg_local, tmp); move16();
+ *pImX-- = mult_r(mag_chg_local, im); move16();
+ }
+
+ i = add(i, 1);
+ ASSERT(pReX == &(X[i]));
+ ASSERT(*pReX == X[i]);
+ if (sub(i, gwlpr_fxPlus1[k]) > 0)
+ {
+ k = add(k, 1);
+ }
+ } /* segment_length Peak*/
+ pCorrPhase_L++;
+ }
+
+ segmentLen = sub(lprotBy2Minus1, sub(i, 1)); /* tail/valley noise-bins */
+
+ /* for 48k the last 63+1+63 = values above 20 kHz */
+ { /* after last, peak no need to scramble above 20kHz , those coeffs have been/ will be zeroed already */
+ /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */
+ /*N: 1, 320 , 63 , 1 , 63 , 320 */
+ /*ind: 0, 1-320, 321-383 ,384 , 385-447, 448 -767 */
+ /* segmentLen = sub(320, i-1); */ /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be
+ zeroed */
+ /* ASSERT(i-1+ segmentLen == lprotBy2Minus1 ); */
+ }
+
+ ASSERT(*pReX == X[i]); /* before a final valley*/
+ FOR(j = 0; j < segmentLen; j++)
+ {
+
+
+ *seed = rand_phase_fx(*seed, &sin_F, &cos_F);
+ rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* should be inlined , tmp=real part */
+
+ *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg);
+ /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */
+ IF(noise_mag_scale_neg != 0)
+ {
+ valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F);
+ /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg */
+ }
+
+ tmp = s_and(tmp, one_peak_flag_mask);
+ im = s_and(im, one_peak_flag_mask);
+ IF(beta[k] != 0)
+ { /* fade2avg path never in first BFI frame */
+
+ alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */
+ tmp2 = mult_r(beta[k], Xavg[k]);
+ {
+ tmp2 = s_and(tmp2, one_peak_flag_mask);
+ }
+
+
+ *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16();
+ *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16();
+ }
+ ELSE
+ {
+
+ *pReX++ = mult_r(mag_chg[k], tmp); move16();
+ *pImX-- = mult_r(mag_chg[k], im); move16();
+ }
+ i = add(i, 1);
+ ASSERT(*pReX == X[i]);
+ if (sub(i, gwlpr_fxPlus1[k]) > 0)
+ {
+ k = add(k, 1);
+ }
+ } /* segment_len last valley */
+
+
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ Word32 *L_wtda_audio, /* o : tda audio Q16 20 ms */
+ const Word16 L, Word8 *scratchBuffer) /* Size = 8 * MAX_L_FRAME */
+ {
+ Word16 i, L2; /*,L4;*/
+ const Word16 *pX;
+ const Word16 *pW;
+ Word32 *p1_L, *p2_L, *p3_L, *p4_L;
+ Word32 *L_w_audio; /*OPt 1 use input buffer , OPT2, may be shortened from 20 ms to 16 ms due to
+ zeroed parts*/
+ Word32 *pY_L, *pa1_L, *pa2_L;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("my_wtda_fx", sizeof(struct {
+ Word16 i, L2; /*,L4;*/
+ const Word16 *pX;
+ const Word16 *pW;
+ Word32 *p1_L, *p2_L, *p3_L, *p4_L;
+ Word32 *L_w_audio; /*OPT 1 use input buffer, OPT2, may be shortened from 20 ms to 16.25+(1.75) ms
+ due to zeroed parts*/
+ Word32 *pY_L, *pa1_L, *pa2_L;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::my_wtda_fx");
+#endif
+
+ L_w_audio = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 2 * MAX_L_FRAME */
+
+ /* |111111|222222|333333|444444 */
+ /* |p1 p2| p3||p4 */
+
+ /* Apply analysis window */
+
+ pX = new_audio;
+ pY_L = L_w_audio;
+
+ pW = win2ms_init;
+ FOR(i = 0; i < ((2 * L / 10)); i++) /* Loop over 2ms window MDCT-ana length */
+ {
+ *pY_L++ = L_mult(*pX++, *pW++); move32();
+ }
+
+ pW = win16ms_center;
+ /* 20 ms - 2ms - 3.75 ms = 14.25 ms */
+ FOR(i = 0; i < (2 * L - (2 * L / 10) - ((3 * 2 * L) / 16));
+ i++) /* Loop over remaining 14.25ms, currently out of a 16 ms stored length */
+ {
+ *pY_L++ = L_mult(*pX++, *pW++); move32();
+ }
+
+
+ /* tda */
+ L2 = shr_pos_pos(L, 1); /* length of tda blocks */
+
+ p1_L = L_w_audio; /* block 1 fwd */
+ p2_L = L_w_audio + L - 1; /* block 2 rev */
+ p3_L = L_w_audio + L + L2 - 1; /* block 3 rev */
+ p4_L = L_w_audio + L + L2; /* block 4 fwd */
+
+ pa1_L = L_wtda_audio; /* first part output */
+ pa2_L = L_wtda_audio + L2; /* second part output */
+
+ FOR(i = 0; i < (L / 8); i++)
+ {
+ /* first 1.25ms part of tda signal -p3_rev -p4_fwd */
+ *pa1_L++ = L_negate(L_add_sat(*p3_L--, *p4_L++)); move32();
+ }
+ FOR(; i < L2; i++)
+ {
+ /* first front part 3.75 ms p4_l is zeroes -p3_rev + (-p4_fwd==0) */
+ *pa1_L++ = L_negate(*p3_L--); move32();
+ }
+
+ FOR(i = 0; i < L2; i++)
+ {
+ /* second part of tda signal p1 -p2_rev */
+ *pa2_L++ = L_sub_sat(*p1_L++, *p2_L--); move32();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return;
+ }
+
+ /*--------------------------------------------------------------------------
+ * rec_wtda()
+ *
+ * Windowing and TDA of reconstructed frame
+ *--------------------------------------------------------------------------*/
+
+
+ static void
+ rec_wtda_fx(
+ Word16 *X, /* i : iFFT(X-evolved) TD-signal o: dbg 16 ms */
+ Word32 *L_ecu_rec, /* o : Reconstructed frame in tda domain Qx? */
+ const Word16 output_frame, /* i : Frame length */
+ const Word16 Lprot, /* i : Prototype frame length */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ const Word16 maxLen,
+ const Word16 *prevsynth,
+ const Word16 Q_psMinus1, /*i: Q prev_synth minus 1 , (-1 to match Q of Xsav in first bfi frame ) */
+ Word8 *scratchBuffer) /* Size = 12 * MAX_L_FRAME */
+ {
+ Word16 l, Lprot2;
+ Word16 *rec_buf;
+ Word16 *xsubst_; /*,*out_ptr;*/
+
+ Word16 ola_old[COPY_LEN_48K + OLA_LEN_48K]; /* 3.75 ms */
+ Word16 work_len;
+ Word16 copy_len;
+ Word16 ola_len;
+
+
+ Word8 *buffer_wtda;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("rec_wtda_fx", sizeof(struct {
+ Word16 l, Lprot2;
+ Word16 *rec_buf;
+ Word16 *xsubst_; /*,*out_ptr;*/
+ Word8 *buffer_wtda;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::rec_wtda_fx");
+#endif
+
+ rec_buf = scratchAlign(scratchBuffer, 0); /* Size = 2 * 2 * MAX_L_FRAME */
+ buffer_wtda = (Word8 *)scratchAlign(rec_buf, sizeof(*rec_buf) * (2 * maxLen)); /* Size = 4 * 2 * MAX_L_FRAME */
+
+ xsubst_ = rec_buf;
+ Lprot2 = shr_pos_pos(Lprot, 1);
+
+ /* extract reconstructed frame with ld window into rec_buf */
+ l = sub(output_frame, Lprot2);
+ basop_memmove(xsubst_ + l, X, (Lprot) * sizeof(Word16)); /* 16 ms IFFT raw output */
+ copy_len = COPY_LEN[FRAME2FS_IDX(output_frame)];
+ ola_len = OLA_LEN[FRAME2FS_IDX(output_frame)];
+ work_len = add(copy_len, ola_len);
+ /* Copy and scale copy part 2ms from prevsynth */
+ basop_memmove(rec_buf, &prevsynth[Lprot - work_len], (copy_len) * sizeof(Word16)); /* 2ms out of 3.75 ms copied */
+ Scale_sig_sat(rec_buf, copy_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Q_ps-4) */
+
+
+ /* Copy, window and scale 1.75 ms ola part from prevsynth , into a temporary buffer ola_old */
+
+
+ windowing_ola(&prevsynth[Lprot - ola_len], ola_old, w_old[FRAME2FS_IDX(output_frame)], ola_len); /* 1.75 ms */
+
+ Scale_sig_sat(ola_old, ola_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Qps-4) */
+
+ /* Window 1.75 ms length inplace recreated X=IFFT(prototype) signal copied into rec_buf signal */
+ windowing_ola(&rec_buf[copy_len], &rec_buf[copy_len], w_new[FRAME2FS_IDX(output_frame)], ola_len);
+ /* mix add the two windowed components */
+ ola_add(&rec_buf[copy_len], ola_old, &rec_buf[copy_len], ola_len); /* OPT: sat check */
+
+ my_wtda_fx(rec_buf,
+ win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ L_ecu_rec, output_frame, buffer_wtda); /* */
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ return;
+ }
+
+ /*--------------------------------------------------------------------------
+ * rec_frame_fx()
+ *
+ * Frame reconstruction
+ *--------------------------------------------------------------------------*/
+ void rec_frame_fx(Word16 * x, /* i : FFT spectrum 16 ms, o: ifft() TD debug signal 16ms */
+ Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain 10ms buffer */
+ const Word16 output_frame, /* i : Frame length */
+ const Word16 Q, /* i : Xsav Q */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ Word16 maxLprot,
+ const Word16 *prevsynth,
+ const Word16 Q_prevsynthMinus1, /* i : prevsynthQ-1 or xfp Q */
+ Word8 *scratchBuffer /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */
+ )
+ {
+ Counter i;
+ Word16 Lprot;
+ Word32 *L_x;
+ Word32 *pX_L;
+ Word16 *pX;
+ Word16 fft_scale;
+ Word8 * buffer_fft;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("rec_frame_fx", sizeof(struct {
+ Counter i;
+ Word16 Lprot;
+ Word32 *L_x;
+ Word32 *pX_L;
+ Word16 *pX;
+ Word16 fft_scale;
+ Word8 * buffer_fft;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::rec_frame_fx");
+#endif
+
+ L_x = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT */
+ buffer_fft = (Word8 *)scratchAlign(L_x, sizeof(*L_x) * maxLprot); /* Size = 4* (2+1) * MAX_L_FRAME */
+
+ /* Initialize to FB constants */
+ Lprot = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */
+ ASSERT(Lprot == (output_frame / 100));
+ Lprot = LprotSzPtr[Lprot]; move16();
+
+
+ /* Convert stored 16 bit into 32bit for fft */
+ flippedW16_2_intlvW32(x, sub(shr_pos_pos(Lprot, 1), 1), Lprot, L_x);
+ /*scratch x now free for re-use */
+
+ fft_scale = -1; move16();
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::IFFT_fx");
+#endif
+ BASOP_irfftN(L_x, Lprot, &fft_scale, buffer_fft);
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ pX_L = &L_x[0];
+ pX = &x[0]; /* scratch x reused */
+
+ {
+ FOR(i = 0; i < Lprot; i++)
+ {
+ *pX++ = extract_h(L_shl_sat(*pX_L++, fft_scale)); move16();
+ }
+ }
+ /* Scratch L_x may be released */
+
+
+ /* Saturation possible when rescaling to Q0 if there are random bit errors in the bit stream
+ * One may use one guard bit to better handle this - though it should not be needed for normal
+ * operation.
+ */
+ Scale_sig_sat(x, Lprot, negate(Q)); /* scale by 2^(-Q) */
+
+ /*scratch x is Lprot word16 */
+ /* scatch need for win-TDA XXX */
+ /* scrcatch need for TDA XXX */
+
+ rec_wtda_fx(x, L_ecu_rec, output_frame, Lprot,
+ win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ s_max(output_frame, 160),
+ prevsynth,
+ Q_prevsynthMinus1, /* NB: prevsynth Q may change from prev_bfi=0 to prev_bfi==1, due to phase
+ of signal or PLC2-muting */
+ buffer_fft);
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return;
+ }
+
+ /*--------------------------------------------------------------------------
+ * hq_phase_ecu_fx()
+ *
+ * Main routine for HQ phase ECU
+ *--------------------------------------------------------------------------*/
+ void hq_phase_ecu_fx(
+ const Word16 *prevsynth, /* i : buffer of previously synthesized signal currently 16ms */
+ Word32 * L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */
+ Word16 * time_offs, /* i/o: Sample offset for consecutive frame losses*/
+ Word16 * X_sav, /* i/o: Stored spectrum of prototype frame */
+ Word16 * Q_spec, /* o: Q value of stored spectrum */
+ Word16 * num_p, /* i/o: Number of identified peaks */
+ Word16 * plocs, /* i/o: Peak locations */
+ Word32 * L_plocsi, /* i/o: Interpolated peak locations Q16 */
+ const Word16 env_stab, /* i : Envelope stability parameter */
+ const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */
+ const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */
+ const Word16 prev_bfi, /* i : indicating burst frame error */
+ Word16 old_is_transient[2], /* i/o : flags indicating noise generation frames */
+ Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients*/
+ Word16 * mag_chg_gr, /* o: per band magnitude modifier, incl burst attenuation */
+ Word16 * Xavg, /* i/o: Frequency group average gain to fade to */
+ Word16 * beta_mute, /* o : Factor for long-term mute */
+ const Word16 bwidth_fx, /* i : Encoded bandwidth */
+ const Word16 output_frame, /* i : frame length */
+ Word16 * seed_out_fxPtr, /* o: utput dbg NULL may be used*/
+ Word16 * X_out, /* o: utput dbg NUll may be used */
+ const Word16 t_adv, /* i : time adjustment including time_offs */
+ const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */
+ const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */
+ const Word16 *sp_ana_win, /* i : whr 3+10+3 window */
+ Word16 q_fx_old_exp, /* i : exp of prev_synth */
+
+ Word16 maxLprot, /* i : maz spectrum buffer size */
+ Word16 maxPlocs, /* i : max nb of peaks */
+ Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signale */
+ Word16 oold_Ltot_exp_fx, /*true exp of energy */
+ Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, /* exp of time signale */
+ Word16 old_Ltot_exp_fx, /*true exp of energy */
+ Word16 *old_grp_shape_fx,
+ Word16 margin_prevsynth,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ const Word16 fadeout,
+ Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */
+#endif
+ Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */
+ )
+ {
+ Word16 lprot;
+ Word16 *mag_chg, ph_dith, *X;
+ Word16 *xfp;
+ Word16 seed;
+ Word16 alpha[MAX_LGW], beta[MAX_LGW] ;
+ Word16 prevsynth_man_upshift;
+ Word16 Q_prevsynthMinus1;
+ Word8 *buffer;
+# ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word32 L_Xavg[MAX_LGW]; /* i/o : Frequency group amp averages for tonal tilt analysis Max upshifted */
+# endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("hq_phase_ecu_fx", sizeof(struct {
+ Counter i;
+ Word16 lprot;
+ Word16 *mag_chg, ph_dith, *X;
+ Word16 seed;
+ Word16 alpha[MAX_LGW], beta[MAX_LGW];
+ Word16 prevsynth_man_upshift;
+ Word16 Q_prevsynthMinus1;
+ Word8 *buffer;
+ // ToDO Word32 L_Xavg[MAX_LGW];
+ }));
+#endif
+
+ if (!prev_bfi)
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::hq_phase_ecu_fx(1st)");
+#endif
+ }
+ else
+ {
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::hq_phase_ecu_fx(N)");
+#endif
+ }
+
+ mag_chg = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LGW */
+ X = (Word16 *)scratchAlign(mag_chg, sizeof(*mag_chg) * MAX_LGW); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */
+ xfp = (Word16 *)scratchAlign(X, sizeof(*X) * maxLprot); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */
+ buffer = (Word8 *)scratchAlign(xfp, sizeof(*xfp) * maxLprot); /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */
+
+ /* buffer size = Word32 * MAX_LPROT (FFT, IFFT) DRAM
+ + 3*Word32 * MAX_L_FRAME */
+
+ basop_memset(alpha, 0, MAX_LGW*sizeof(Word16));
+ basop_memset(beta, 0, MAX_LGW*sizeof(Word16));
+
+ lprot = LprotSzPtr[bwidth_fx]; move16();
+
+ test();
+ ASSERT(prev_bfi >= 0 && prev_bfi <= 1);
+ IF( prev_bfi == 0 ) /* inside PhECU we can check vs 0 */
+ {
+ *time_offs = 0; move16();
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ *nonpure_tone_flag_ptr = -1; move16(); /* flag nonpure tone flag for new analysis */
+#endif
+ /* analysis made outside, up/down scaling here from static RAM to dynamic RAM */
+ /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */
+ /* X_sav_flt = X_man/2.^(Q_spec) */
+
+ /* 1 bit headroom needed in xfp_tmp_buf for FFT processing into X_sav */
+ /* margin_prevsynth = actual margin in incoming 16 ms xpf segment */
+ /* q_fx_old_exp was computed on full 21+ ms updatepcm buffer) */
+
+ ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 16));
+
+ prevsynth_man_upshift =
+ sub(margin_prevsynth, 1); /* 0 --> -1(==down), 1--> 0 , 2 --> 1(==up), ... */
+ ASSERT(prevsynth_man_upshift >= -16 && prevsynth_man_upshift <= 15); /* avoid Overflow in shr, shl */
+ *Q_spec = sub(15, sub(q_fx_old_exp, prevsynth_man_upshift));
+ /* Q_spec target is to create 1 additional bit of margin in the xfp TD buffer , before converting to
+ * Xsav
+ */
+
+ if (margin_prevsynth == 0)
+ {
+ Word16 Qold = 15 - (q_fx_old_exp + 1);
+ Word16 tmp_man_upshift = margin_prevsynth - 1; /* 1 .. -15 */
+ Word16 Qnew = 15 - (q_fx_old_exp - tmp_man_upshift);
+ assert(Qold == Qnew);
+ UNUSED(Qold);
+ UNUSED(Qnew);
+ }
+ if (margin_prevsynth == 1)
+ {
+ Word16 Qold = 15 - (q_fx_old_exp + 0);
+ assert(*Q_spec == Qold);
+ UNUSED(Qold);
+ }
+ if (margin_prevsynth == 2)
+ {
+ Word16 Qold = 15 - (q_fx_old_exp - 1);
+ assert(*Q_spec == Qold);
+ UNUSED(Qold);
+ }
+
+ Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* dbg to use non-scaled prevsynth for OLA */
+
+ /* Q of prev_synth now separated from prev_bfi=0 and prev_bfi==1 */
+
+#ifdef USE_TMPXFP_IN_OLA
+ Q_prevsynthMinus1 = *Q_spec; /* a possibly upscaled Q */
+#endif
+
+
+ Copy_Scale_sig(
+ prevsynth, xfp, lprot,
+ prevsynth_man_upshift); /* unscaled prevsynth is still used by rec_frame, copy to a temporary
+ xfp analysis buffer, and scale down to a margin of 1 bit */
+
+
+ trans_burst_ana_fx(
+ ((void *)NULL),
+ mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg,
+ (*Q_spec), L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx,
+ L_old_xfp_w_E_fx, old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ fadeout,
+ L_Xavg, /* full scale band amplitudes in first bfi frame */
+#endif
+ buffer);
+
+ spec_ana_fx(&(xfp[0]), plocs, L_plocsi, num_p, X_sav, output_frame, bwidth_fx,
+ sp_ana_win, f0hzLtpBinQ7, norm_corrQ15_fx, maxLprot, maxPlocs, buffer);
+ }
+ ELSE
+ {
+ /* analysis made outside, possible up/down scaling here from static RAM to dynamic RAM */
+ ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 15));
+
+ /* prev_synth may have been scaled outside by update_pcm() function */
+ /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */
+ /* first bfi frame: X_sav_flt = X_man/2.^(*Q_spec) */
+ /* this bfi frame prev_synth(TD) is mixed with ifft signal(TD,from Q_spec) in rec_frame_fx
+ variable Q_prevsynthMinus1 provided to rec_frame for this TD+TD mixing
+ */
+
+ Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* for now, "old" use of unscaled prevsynth for added OLA */
+
+#ifdef USE_TMPXFP_IN_OLA
+ { /* DBG target here is to instead upshift to a zero margin */
+ /* but Q value is maintained to match the save Xsav *Q_spec which is used with an offset of " -1" */
+ /* prevsynth_man_upshift = -prevsynth_margin ; */
+ Word16 tmp, worklen = add(hamm_len2Tab[bwidth_fx], shr(hamm_len2Tab[bwidth_fx], 2));
+ tmp = mult(7680, lprot); /* needs to truncate to integer */
+ ASSERT(tmp == worklen);
+ Copy_Scale_sig(&prevsynth[lprot - worklen], &xfp[lprot - worklen], worklen,
+ margin_prevsynth); /* only scale up last 3.75 ms */
+ Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, margin_prevsynth)); /*-1 does not make sense */
+ }
+#endif
+
+ *time_offs = add_sat(*time_offs, output_frame);
+
+ trans_burst_ana_fx(
+ ((void *)NULL),
+ mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg,
+ (0), /* *Q_spec input only used in first bfi frames for burst analysis */
+ L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx, L_old_xfp_w_E_fx,
+ old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx,
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ fadeout,
+ NULL, /* full scale band amplitudes , only used in first bfi frame */
+#endif
+ buffer);
+ }
+ /* cpy LPROT Word16 from Static RAM Xsav to working DRAM/scratch buffer X ;*/
+ basop_memmove(X, X_sav, (lprot) * sizeof(Word16));
+ /* seed for own_rand2 */
+ seed = *time_offs; move16();
+
+ if (mag_chg_gr != NULL) /* o: dbg per band magnitude modifier, incl. burst attenuation */
+ {
+ Counter k;
+ Word16 lgw_local = s_min(add(bwidth_fx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */
+ for (k = 0; k < lgw_local; k++)
+ {
+ mag_chg_gr[k] = mag_chg[k]; /* dbg SNR output */
+ }
+ }
+
+ subst_spec_fx(plocs, L_plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame,
+ &seed, alpha, beta,
+ Xavg, t_adv
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ ,fadeout,
+ nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */
+ L_Xavg /*i : only used in first bfi frame */
+#endif
+ );
+
+ if (seed_out_fxPtr != NULL)
+ {
+ *seed_out_fxPtr = seed; /* verify seed synch after subst_spec */
+ }
+
+
+ if (X_out != NULL)
+ {
+ Word16 ii;
+ for (ii = 0; ii < lprot; ii++)
+ {
+ X_out[ii] = X[ii]; /* evolve spectrum, no moves counted as this is a dbg-vector info cpy */
+ }
+ }
+
+ /* reconstructed frame in tda domain */
+ /* NB *Q_spec only updated in first bfi frame */
+
+ /*Scratch Analysis at this point */
+ /* X fft input needed as evolved spectrum Lprot* Word16 */
+ /* xfp not needed any longer Word16* Lprot */
+ /* IFFT operation needs Word32*Lprot in and Word32*Lprot out */
+ /* MDCT win operation may be inplace 2x MAX_L_FRAME */
+ /* TDA output is 1x MAX_L_FRAME */
+
+ rec_frame_fx(X, L_ecu_rec, output_frame, *Q_spec,
+ win2ms_init, win16ms_center,
+ maxLprot,
+#ifdef USE_TMPXFP_IN_OLA
+ xfp, /* only last 3.75 ms used, in both prevbfi=0 and prevBfi=1 i.e frames, xfp is an
+ upscaled prev_synth */
+#else
+ prevsynth, /*only last 3.75 ms used in both prevbfi=0 and prevBfi=1 i.e frames */
+#endif
+ Q_prevsynthMinus1,
+ buffer);
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+
+ static Word16 sqrt2ndOrder( /* o: in Q15 (2nd order least square approx.) */
+ const Word16 x /* i: x must be in between 0.5 and 1.0 (Q15). */
+ )
+ {
+ Word32 acc;
+ Word16 z;
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::sqrt2ndOrder");
+#endif
+
+ ASSERT(x >= 16384);
+
+ acc = 1890205600L; /* 0.880195572812922 in Q31 */ move32();
+ z = mac_r(acc, x, -6506); /* -0.198537395405340 in Q15 */
+ acc = 682030261L; /* 0.317595089462249 in Q31 */ move32();
+ z = mac_r(acc, z, x); /* in Q15 */
+
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return z;
+ }
+
+
+ /* Modified version to produce Word32 input to FFT */
+ static void windowing_L(
+ const Word16 *x, /* i: Input signal */
+ Word32 * L_y, /* o: Windowed output */
+ const Word16 *win, /* i: Window coefficients */
+ const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */
+ const Word16 halfLength /* i: Half of the total length of a complete Hamming window. */
+ )
+ {
+ Counter i;
+ Word32 * pY_L;
+ const Word16 *pX, *pW;
+ Word16 tmp_RL;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("windowing_L", sizeof(struct {
+ Counter i;
+ Word32 * pY_L;
+ const Word16 *pX, *pW;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::windowing_L");
+#endif
+
+ pX = x;
+ pW = win;
+ pY_L = L_y;
+
+ FOR(i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */
+ {
+ *pY_L++ = L_mult(*pX++, *pW++); move32();
+ }
+ /* Periodic filter - one more rect sample before end tapering */
+
+ tmp_RL = add(rectLength, 1);
+
+ if (rectLength == 0)
+ {
+ tmp_RL = 0; move16();
+ }
+ /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */
+ FOR(i = 0; i < tmp_RL;i++)
+ {
+ *pY_L++ = L_deposit_h(*pX++); move32();
+ }
+ tmp_RL = sub(halfLength, 1);
+ if (rectLength == 0)
+ {
+ tmp_RL = halfLength; move16();
+ }
+ FOR(i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */
+ {
+ *pY_L++ = L_mult(*pX++, *(--pW)); move32();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ /* Modified version to produce Word16 input to FFT */
+ static void windowing_ola(const Word16 *x, /* i: Input signal */
+ Word16 * y, /* o: Windowed output */
+ const Word16 *win, /* i: Window coefficients */
+ const Word16 Length /* i: Half of the total length of a complete Hamming window. */
+ )
+ {
+ Counter i;
+ Word16 * pY;
+ const Word16 *pX, *pW;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("windowing_ola", sizeof(struct {
+ Counter i;
+ Word16 * pY;
+ const Word16 *pX, *pW;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::windowing_ola");
+#endif
+
+ pX = x;
+ pW = win;
+ pY = y;
+
+ FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */
+ {
+ *pY++ = mult_r(*pX++, *pW++); move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ /* Modified version to produce Word16 input to FFT */
+ static void ola_add(const Word16 *x, /* i: Input signal 1 */
+ const Word16 *y, /* i: Input signal 2 */
+ Word16 * z, /* o: Output signal */
+ const Word16 Length /* i: Half of the total length of a complete window. */
+ )
+ {
+ Counter i;
+ Word16 * pZ;
+ const Word16 *pX, *pY;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("windowing_ola", sizeof(struct {
+ Counter i;
+ Word16 * pY;
+ const Word16 *pX, *pW;
+ }));
+#endif
+
+
+
+ pX = x;
+ pY = y;
+ pZ = z;
+
+ FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */
+ {
+ *pZ++ = add_sat(*pX++, *pY++); move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+ }
+
+ /*-----------------------------------------------------------------------------
+ * magnSqrtApprox_fx()
+ *
+ * Approximation of sqrt(Square magnitude) of fft spectrum
+ * if min_abs <= 0.4142135*max_abs
+ * abs = 0.99*max_abs + 0.197*min_abs
+ * else
+ * abs = 0.84*max_abs + 0.561*min_abs
+ * end
+ *
+ * Note: even to handle the dynamics of sqrt(re^2+im^2) located on
+ * a scaled unit circle. One need to scale down the results
+ * with a factor 2, that is Q_out = Q_in - 1
+ * sqrt(32768.^2+32768.^2) results in = 23170 Q0-1,
+ * which corresponds to 46341 in the Q0 domain
+ *----------------------------------------------------------------------------*/
+ Word16 sqrtMagnApprox_fx( /* o : sqrt of magnitude square spectrum Q_in-1*/
+ const Word16 re, /* i : Real part Q_in */
+ const Word16 im /* i : Imag part Q_in */
+ )
+ {
+ /* Constants for Approximation of sqrt(Square magnitude) of fft spectrum
+ * >> num2str(round(0.4142135]*2.^15))
+ * ans = 13573
+ * >> num2str(round([0.99 0.197 0.84 0.561]*2.^14))
+ * ans = 16220 3228 13763 9191
+ */
+
+#define C_0p4142135_Q15 13573
+
+#define C_0p99_Q14 16220
+#define C_0p197_Q14 3228
+#define C_0p84_Q14 13763
+#define C_0p561_Q14 9191
+ Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum;
+ Word16 jcoeffs[2][2] = { {C_0p99_Q14, C_0p197_Q14}, {C_0p84_Q14, C_0p561_Q14} };
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("sqrtMagnApprox_fx", sizeof(struct {
+ Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum;
+ Word16 jcoeffs[2][2];
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::sqrtMagnApprox_fx");
+#endif
+
+ /* Get values and move pointers */
+ re_abs = abs_s(re); /* 1 cycle */
+ im_abs = abs_s(im); /* 1 cycle */
+
+ /* Find max and min value */
+ min_abs = s_min(re_abs, im_abs); /* 1 cycle */
+ max_abs = s_max(re_abs, im_abs); /* 1 cycle */
+
+ /* Calc approximation depending on relation */
+ sgn_bit = lshr(sub(mult(max_abs, C_0p4142135_Q15), min_abs), 15); /* 3 cycles */
+ sum = mac_r(L_mult(max_abs, jcoeffs[sgn_bit][0]), min_abs, jcoeffs[sgn_bit][1]); /* 2 cycles */
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return sum;
+ }
+
+ /*-----------------------------------------------------------------------------
+ * fft_spec2_sqrt_approx_fx()
+ *
+ * Approximation of sqrt(Square magnitude) of fft spectrum
+ * if min_abs <= 0.4142135*max_abs
+ * abs = 0.99 max_abs + 0.197*min_abs
+ * else
+ * abs = 0.84 max_abs + 0.561*min_abs
+ * end
+ *
+ * Note: even to handle the dynamics of sqrt(re^2+im^2) located on
+ * a scaled unit circle. One need to scale down the results
+ * with a factor 2, that is Q_out = Q_in - 1
+ * sqrt( -32768.^2 + -32768.^2 ) results in = 23170 Qin-1,
+ * which corresponds to 46341 in the Qin domain
+ *----------------------------------------------------------------------------*/
+
+ void fft_spec2_sqrt_approx_fx(const Word16 x[], /* i : Input vector: complex spectrum , Qin */
+ Word16 xMagSqrt[], /* o : sqrt of magnitude square spectrum Qout=Qin-1*/
+ const Word16 N /* i : Input vector x length */
+ )
+ {
+ Counter i;
+ Word16 l;
+ const Word16 *pRe, *pIm;
+ Word16 * pMagSqrt;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("fft_spec2_sqrt_approx_fx", sizeof(struct {
+ Counter i;
+ Word16 l;
+ const Word16 *pRe, *pIm;
+ Word16 * pMagSqrt;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::fft_spec2_sqrt_approx_fx");
+#endif
+
+ /* Magnitude at 0. only real component */
+ pMagSqrt = &xMagSqrt[0];
+ pRe = &x[0];
+ *pMagSqrt++ = mult(abs_s(*pRe++), C_0p99_Q14); move16();
+
+ /* From 1 to (N/2 - 1). */
+ pIm = &x[N - 1];
+
+ l = sub(shr_pos_pos(N, 1), 1); /* N/2 - 1. */
+ l = s_min(l, (LPROT48K_RED / 2 - 1) + DELTA_CORR_F0_INT);
+ /* at 48 k the top 8 khz are always zero, and further peaks are not
+ located above LPROT48K_RED 32 kHz */
+ FOR(i = 0; i < l; i++)
+ {
+ *pMagSqrt++ = sqrtMagnApprox_fx(*pRe++, *pIm--); move16();
+ }
+
+ /* The sqrt magnitude square at N/2 - only real component */
+ *pMagSqrt = mult(abs_s(*pRe), C_0p99_Q14); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return;
+ }
+
+ Word16
+ imax2_jacobsen_mag_fx(/* o: The location, relative to the middle of the 3 given data point, of the maximum.
+ (Q15) */
+ const Word16 *y_re, /* i: The 3 given data points. real part order -1 0 1 */
+ const Word16 *y_im, /* i: The 3 given data points. imag part order 1 0 -1 (from FFT)*/
+ const Word16
+ special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */
+ )
+ {
+ Word16 posi;
+ Word16 man, expo;
+ const Word16 *pY;
+ Word16 y_m1_re, y_0_re, y_p1_re;
+ Word16 y_m1_im, y_0_im, y_p1_im;
+
+ Word16 D_re, D_im, N_re, N_im;
+
+ Word32 L_sign, L_denom, L_numer;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("imax2_jacobsen_mag_fx", sizeof(struct {
+ Word16 posi;
+ Word16 man, expo;
+ const Word16 *pY;
+ Word16 y_m1_re, y_0_re, y_p1_re;
+ Word16 y_m1_im, y_0_im, y_p1_im;
+ Word16 D_re, D_im, N_re, N_im;
+ Word32 L_sign, L_denom, L_numer;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::imax2_jacobsen_mag_fx");
+#endif
+
+ /* Jacobsen estimates peak offset relative y_0 using
+ * X_m1 - X_p1
+ * d = REAL ( ------------------- ) * c_jacob
+ * 2*X_0 - X_m1 -Xp1
+ *
+ * Where c_jacob is a window dependent constant
+ */
+#define C_JACOB_Q14 18725 /* c_jacob = 1.1429; % assume 0.1875 hammrect window 'periodic' */
+
+ ASSERT(special == 0); /* always use other imax for edges cases */
+ UNUSED(special);
+
+ /* Get the bin parameters into variables */
+ pY = y_re;
+ y_m1_re = *pY++;
+ y_0_re = *pY++;
+ y_p1_re = *pY++;
+
+ /* Same for imaginary parts - note reverse order from FFT */
+ pY = y_im;
+ y_p1_im = *pY++;
+ y_0_im = *pY++;
+ y_m1_im = *pY++;
+
+ test();
+ IF( norm_s(y_0_re) == 0 || norm_s(y_0_im) == 0 )
+ {
+#define JACOB_MARGIN 2
+ /* for very high peaks the Complex denominator values may need to be downshifted 2 steps */
+ y_0_re = shr_pos(y_0_re, JACOB_MARGIN);
+ y_0_im = shr_pos(y_0_im, JACOB_MARGIN);
+
+ y_m1_re = shr_pos(y_m1_re, JACOB_MARGIN);
+ y_m1_im = shr_pos(y_m1_im, JACOB_MARGIN);
+
+ y_p1_re = shr_pos(y_p1_re, JACOB_MARGIN);
+ y_p1_im = shr_pos(y_p1_im, JACOB_MARGIN);
+ }
+
+ /* prepare numerator real and imaginary parts*/
+ N_re = sub(y_m1_re, y_p1_re);
+ N_im = sub(y_m1_im, y_p1_im);
+
+ /* prepare denominator real and imaginary parts */
+
+ D_re = sub(sub(shl_pos(y_0_re, 1), y_m1_re), y_p1_re);
+ D_im = sub(sub(shl_pos(y_0_im, 1), y_m1_im), y_p1_im);
+
+ /* REAL part of complex division */
+ L_numer = L_mac0(L_mult0(N_re, D_re), N_im, D_im);
+ L_denom = L_mac0(L_mult0(D_re, D_re), D_im, D_im);
+ L_sign = L_xor(L_numer, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */
+
+ L_numer = L_abs(L_numer);
+ L_denom = L_abs(L_denom);
+
+ test();
+ IF(L_numer != 0 && L_denom != 0)
+ {
+
+ man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */
+
+ man = mult_r(man, C_JACOB_Q14);
+ posi = shr_sat( man, sub(expo, 2));
+ /* to Q15 (and due to saturation, it is automatically bound inside [-1.0,1.0].) */
+
+ if (L_sign < 0) /* Restore the sign. */
+ {
+ posi = negate(posi);
+ }
+ }
+ ELSE
+ {
+ posi = 0; move16(); /* flat top, division is not possible choose center freq */
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return posi; /* Q15. The position either left or right relative to the index of the middle of the 3 given
+ data points. */
+ }
+
+ /* Convert 32 Bit FFT into 16 bit fft domain */
+ static void intlvW32_2_flippedW16(
+ Word32 * L_x, /* i : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */
+ const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */
+ const Word16 Lprot, /* i: fft size , including DC+fs/2 */
+ Word16 * x /* o : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */
+ )
+ {
+
+ /* reorder real and imag components, and apply fractional scale for 24/48Khz */
+ Counter m;
+ Counter numPairsLocal;
+ Word32 *pX_L = &L_x[2]; /*ptr init*/
+ Word16 *pX_Re = &x[1]; /*ptr init*/
+ Word16 *pX_Im = &x[Lprot - 1]; /*ptr init*/
+
+#define FHG_FFT_UPSHIFT 2
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::intlvW32_2_flippedW16");
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("intlvW32_2_flippedW16", sizeof(struct {
+ Counter m;
+ Counter numPairsLocal;
+ Word32 *pX_L;
+ Word16 *pX_Re;
+ Word16 *pX_Im;
+ }));
+#endif
+
+ /* make the scaling of 8/3= 4*0.666 here for 24 kHz and 48 kHz using 16x16 instead or 32x16 ops
+ a limited loss of SNR */
+
+ test();
+ IF(sub(numPairs, 383) == 0 || sub(numPairs, 191) == 0)
+ { /* 24,48 kHz , 16 ms , scale by 8/3 = .666*4 */
+ numPairsLocal = s_min(numPairs, 383 - 63); /* do not copy bins above 20 kHz */
+ /* for 48 kHz is to only go up to 40 kHz pairs , */
+ FOR(m = 0; m < numPairsLocal; m++)
+ {
+ /* multiply by (8/3)*(2.^FHG_FFT_UPSHIFT) */
+ /* note: multiplication by 2/3 need to preceed upshift , due to FFT scaling being very close to the 48/24 3
+ * split kHz bit margin */
+ *pX_Re++ = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2));
+ move16();
+ *pX_Im-- = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2));
+ move16();
+ }
+ /* Place the two real only components */
+ x[0] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[0], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* DC */
+ move16();
+ m = shr_pos_pos(Lprot, 1);
+ x[m] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[1], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* fs/2 */
+ move16();
+ }
+ ELSE
+ { /* 8,16,32 kHz 16 ms no additional scaling by 8/3 */
+
+ FOR(m = 0; m < numPairs; m++)
+ {
+ *pX_Re++ = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT));
+ move16();
+ *pX_Im-- = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT));
+ move16();
+ }
+
+ /* Place the two real only components */
+ x[0] = extract_h(L_shl_pos(L_x[0], FHG_FFT_UPSHIFT)); /* DC */ move16();
+ m = shr_pos_pos(Lprot, 1);
+ x[m] = extract_h(L_shl_pos(L_x[1], FHG_FFT_UPSHIFT)); /* fs/2 */ move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ static void flippedW16_2_intlvW32(
+ Word16 * x, /* i : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */
+ const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */
+ const Word16 Lprot, /* i: fft size , including DC+fs/2 */
+ Word32 * L_x /* o : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */
+ )
+ {
+ Counter i;
+ Counter numPairsLocal;
+ Word32 *pX_L;
+ Word16 *pX_re, *pX_im;
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::flippedW16_2_intlvW32");
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("flippedW16_2_intlvW32", sizeof(struct {
+ Counter i;
+ Counter numPairsLocal;
+ Word32 *pX_L;
+ Word16 *pX_re, *pX_im;
+ }));
+#endif
+
+ /* Convert stored 16 bit into 32bit for fft */
+ /* Note during save FFT output was left shifted FHG_FFT_UPSHIFT */
+ /* this needs to be restored before one calls ifft to avoid overflow */
+
+ pX_L = &L_x[2]; /*ptr init*/
+ pX_re = &x[1]; /*ptr init*/
+ pX_im = &x[Lprot - 1]; /*ptr init*/
+
+ numPairsLocal = s_min(320, numPairs); /* 48kHz optimization */
+ FOR(i = 0; i < numPairsLocal; i++)
+ {
+ *pX_L++ = L_shr_pos(L_deposit_h(*pX_re++), FHG_FFT_UPSHIFT); move32();
+ *pX_L++ = L_shr_pos(L_deposit_h(*pX_im--), FHG_FFT_UPSHIFT); move32();
+ }
+ /* at 48KHz zero tail 2x63= 126 bins for Word32 IFFT input */
+ basop_memset(pX_L, 0, sizeof(Word32) * shl_pos(sub(numPairs, numPairsLocal), 1));
+
+ /* Place the two real only components */
+ L_x[0] = L_shr_pos(L_deposit_h(x[0]), FHG_FFT_UPSHIFT); move32();
+ L_x[1] = L_shr_pos(L_deposit_h(x[Lprot / 2]), FHG_FFT_UPSHIFT); move32();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+ void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */
+ Word16 * ptrSin, /* Q15 */
+ Word16 * ptrCos /* Q15 */
+ )
+ {
+ Word16 sign_val, idx, idx2, idx3;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("get_sin_cosQ10", sizeof(struct { Word16 sign_val, idx, idx2, idx3; }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::get_sin_cosQ10opt");
+#endif
+
+ /* sin table has a range up to pi/2 (256+1)=257 coeffs*/
+
+ sign_val = shr_pos_pos(phase, 9); /* highest bit is the sinus sign */
+ idx = s_and(phase, 0x1ff); /* mask away sign */
+
+ idx2 = sub(idx, 256);
+ if (idx2 < 0)
+ { /*rising sine part */
+ *ptrSin = sin_quarterQ15_fx[idx]; move16();
+ }
+
+ idx3 = sub(512, idx);
+ if (idx2 >= 0)
+ { /* decaying part, reverse idx */
+ *ptrSin = sin_quarterQ15_fx[idx3]; move16();
+ }
+
+ if (sign_val != 0)
+ {
+ *ptrSin = negate(*ptrSin); /*no move when inlined , no sat as max in table is 32767 */
+ }
+
+ /*cos*/
+ idx = add(phase, 256); /* +pi/2, i.e. move to cos phase */
+ idx = s_and(idx, 0x3ff); /* wrap on 10 bits limit */
+
+ sign_val = shr_pos_pos(idx, 9); /* highest bit is the sign */
+ idx = s_and(idx, 0x1ff); /* mask away sign */
+
+ idx2 = sub(idx, 256);
+ if (idx2 < 0)
+ { /*rising sine part */
+ *ptrCos = sin_quarterQ15_fx[idx]; move16();
+ }
+
+ idx3 = sub(512, idx);
+ if (idx2 >= 0)
+ { /* decaying part, reverse idx*/
+ *ptrCos = sin_quarterQ15_fx[idx3]; move16();
+ }
+
+ if (sign_val != 0)
+ {
+ *ptrCos = negate(*ptrCos); /* no move when inlined , no sat as max in table is 32767 */
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ }
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs,
+ const Word16 n_plocs,
+ const Word16* X, /*i: { DC, Re1,Re2 ,.....ReN , Fs/2, ImN... , Im2, Im1} */
+ const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */
+ const Word16 Lprot,
+ const Word16 fs_idx)
+ {
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("PhECU::nonpure_tone_ana", sizeof(struct {
+ Word16 nonpure_tone_detect;
+ Word16 n_ind, tone_ind, low_ind, high_ind;
+ Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)];
+ Word16 sineband_ind_low, sineband_ind_high;
+ Word16 i, N_grp;
+ Word16 tmp, tmp_dB;
+ Word32 L_tot_inc_HF, L_tot_inc_LF;
+ Word16* pRe;
+ Word16* pIm;
+ Word16* gwlpr_fxPlus1;
+ Word32 L_nf;
+ Word32 L_XavgL2_fx[MAX_LGW + 1];
+ Word32 L_XavgUp_fx[MAX_LGW + 1];
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhEcu::nonpure_tone_ana_fx");
+#endif
+
+ Word16 nonpure_tone_detect; /* output variable */
+ Word16 n_ind, tone_ind, low_ind, high_ind;
+ Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)];
+
+ Word16 sineband_ind_low, sineband_ind_high;
+ Word16 i, N_grp;
+ Word16 tmp;
+
+ Word32 L_Ltot_inc_HF, L_Ltot_inc_LF;
+ Word32 L_tmp_dB;
+
+ const Word16* pRe;
+ const Word16* pIm;
+ const Word16* gwlpr_fxPlus1;
+ Word32 L_nf;
+ Word32 L_XavgL2_fx[MAX_LGW + 1], L_tmp ;
+ Word32 L_XavgUp_fx[MAX_LGW + 1]; /* upscaled values , excluding peak band(s) */
+
+ /* use of a compressed hearing sensitivity curve allowing more energy deviation in highest and lowest bands */
+ /* ROM table Word16 scATHFx[MAX_LGW - 1] */
+
+ /* init */
+ nonpure_tone_detect = 0; move16(); /* Word16 register with decisions */
+
+ peak_amp = 0; move16();
+ peak_amp2 = 0; move16();
+
+ /* limit single sine optimization to when 2 peaks are close enough to represent a single sinusoid */
+ test();
+ if ((sub(n_plocs, 2) == 0) &&
+ (sub(sub(plocs[1], plocs[0]), ONE_SIDED_SINE_WIDTH) >= 0)
+ ) /* NB, plocs is an ordered vector */
+ {
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x01);
+ }
+
+ /* local bin wise dynamics analysis, for 1 or 2 initial local maxima peaks ,
+ if 2 peaks , we do the analysis based on the location of the largest abs peak */
+ {
+ tone_ind = 0; move16(); /* one peak only , use position plocs[tone_ind], tone_ind==0 */
+
+ peak_amp = shr(abs_s(X[0]), 1); /* plocs[0]=0, simply multiply DC*0.5 to match scaling in function sqrtMagnApprox_fx */
+ test();
+ IF(plocs[0] != 0)
+ {
+ peak_amp = sqrtMagnApprox_fx(X[plocs[0]], X[sub(Lprot, plocs[0])]);
+ }
+
+ IF(sub(n_plocs, 2) == 0) /* locate abs max peak */
+ {
+ peak_amp2 = sqrtMagnApprox_fx(X[plocs[1]], X[sub(Lprot, plocs[1])]); /* Re-part and Im-part in different ends of array X */
+
+ tmp = sub(peak_amp, peak_amp2);
+ tone_ind = lshr(tmp, 15); /* mask out sign bit 0(for peak_amp0), 1( for peak_amp2), lshr --> no sign extension in shift */
+ peak_amp = s_max(peak_amp, peak_amp2);
+ }
+
+ low_ind = s_max(1, sub(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* DC is not allowed in the range */
+ high_ind = s_min(sub(shr(Lprot, 1), 2), add(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* Fs/2 is not allowed in the range */
+
+ n_ind = add(sub(high_ind, low_ind), 1);
+ /* find lowest amplitude around the assumed main lobe center location */
+
+ pRe = &(X[low_ind]); /* ptr init */
+ pIm = &(X[Lprot - low_ind]); /* ptr init*/
+ FOR(i = 0; i < n_ind; i++)
+ {
+ x_abs[i] = sqrtMagnApprox_fx(*pRe++, *pIm--); move16(); /* x_abs is downscaled by 0.5 in abs(complex) approximation */
+ }
+
+ valley_amp = peak_amp; move16();
+ FOR(i = 0; i < n_ind; i++)
+ {
+ valley_amp = s_min(x_abs[i], valley_amp);
+ }
+
+ /* at least a localized amplitude ratio of 16 (24 dB) required to declare a pure noise-free sinusoid */
+ if (sub(shr(peak_amp, 4), valley_amp) < 0) /* 1/16 */
+ {
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x02); /* not a pure tone due to too low local SNR P2V */
+ }
+ }
+
+
+ /* analyze LF/ HF bands energy dynamics vs the assumed single tone band ( for one or two peaks found cases ) */
+ {
+ /* Xavg , is a vector of rather rough MDCT based band amplitude estimates in perceptually motivated bands. from approx the last 26 ms of synthesis */
+
+ /* eval amplitude relations for assumed tonal band vs lower and higher bands */
+ /*N_grp = xavg_N_grp[fs_idx];*/ /* { 4 NB , 5 WB , 6 SSWB , 7 SWB, 8 FB }; */
+ N_grp = add(fs_idx, 4);
+ assert(fs_idx < 5);
+
+
+ /* establish band(s) with assumed sinusoid tone */
+ /* if tone freq location is below first MDCT-band definition, use first band as band location anyway */
+
+ /* band 0 , 1 , 2 , 3 , ...*/
+ /* dct-inds "c" "0"...11, 12...19, 20...35, 36 ... */
+ /* gwplr_fx= [ 1 , 12(750Hz), 20(1250Hz) , 36 , ... */ /* lowest lim+1 in gwplr */
+
+ /* for-loop BASOP version */
+ tmp = 0; move16();
+ gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */
+ FOR(i = 0; i < N_grp; i++)
+ {
+ if (sub(plocs[tone_ind], gwlpr_fxPlus1[i]) >= 0)
+ {
+ tmp = add(i, 1);
+ }
+ }
+
+ sineband_ind_low = tmp; move16();
+ sineband_ind_high = tmp; move16(); /* typically in the same band as low */
+
+ /* a single tone may end up on a band border
+ , handle case when assumed tone is more or less right in-between two perceptual bands +/- 4*62.5 Hz */
+
+ test(); logic16();
+ if ((sineband_ind_high > 0) &&
+ (sub(sub(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_high, 1)]) >= 0)
+ )
+ {
+ sineband_ind_low = sub(sineband_ind_high, 1);
+ }
+
+ logic16();
+ if ((sub(sineband_ind_low, sub(N_grp, 1)) < 0) &&
+ (sub(add(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_low, 1)]) >= 0)
+ )
+ {
+ sineband_ind_high = add(sineband_ind_low, 1);
+ }
+ }
+
+ /* intraframe(26 ms), weighted LB and HB envelope dynamics/variation analysis */
+ /* envelope analysis ,
+ require at least two HF or two LF bands in the envelope taper/roll-off analysis , otherwise skip this condition */
+
+ logic16();
+ test(); logic16();
+ IF( (nonpure_tone_detect == 0) &&
+ ( (sub( add(sineband_ind_high, 2), N_grp) < 0 ) ||
+ (sub(sineband_ind_low, 2+1 ) >= 0)
+ )
+ )
+ {
+
+ /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */
+
+ /* test Xavg Word16 result above vs a high resolution Word32 L_Xavg */
+ /* strong spectral tilt causes HF to be truncated in Word16 */
+
+ basop_memcpy(L_XavgUp_fx, L_Xavg, N_grp * sizeof(Word32) ) ;
+
+ /* first remove all energy from the assumed tonal peak band(s) */
+ L_XavgUp_fx[sineband_ind_low] = L_min(L_XavgUp_fx[sineband_ind_low], 1); move32();
+ L_XavgUp_fx[sineband_ind_high] = L_min(L_XavgUp_fx[sineband_ind_high], 1); move32();
+
+ tmp = getScaleFactor32_0(L_XavgUp_fx, N_grp); /* o: measured headroom in range [0..32], 32 if all L_x[i] == 0 */
+ if (sub(tmp, 32) == 0)
+ {
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x100); /* also set a flag for an all zero L_Xavg coarse spectrum estimate signal */
+ }
+
+
+ /* add noise floor to L_Xavg before log2 function call */
+ L_nf = L_shl(1L, sub(tmp, 1));
+ L_nf = L_max(L_nf, 1L);
+ for (i = 0; i < N_grp; i++)
+ {
+ L_XavgUp_fx[i] = L_shl_sat(L_XavgUp_fx[i], tmp); move32(); /* maximize precision before actual log2_fx(Word32) calc call */
+
+ L_tmp = L_XavgUp_fx[i]; move32();
+ test();
+ if (L_tmp <= 0)
+ {
+ L_tmp = L_nf; move32();
+ }
+
+ /* log2(Upshifted Word32) */
+ /* maximize precision in BASOP Log2 function */
+ L_XavgL2_fx[i] = BASOP_Util_Log2_lc3plus(L_tmp); /* L_input 1.0 or lower --> output always negative */
+ /* add 31.0 to store as fractional bits of an upscaled positive Word32 integer input ) */
+ L_XavgL2_fx[i] = L_add(31L << 25, L_XavgL2_fx[i]); /* only diffs added so 31.0 is cancelled out later , in total only values between +/- 2^6 = [-64 ... -64[ are possible */
+ } /* band i for L_Xavg calc*/
+ /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */
+ L_Ltot_inc_HF = 0; move32();
+ for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++)
+ {
+ L_tmp_dB = 0; move32();
+ if (L_sub(L_Xavg[i], L_Xavg[i + 1]) < 0) /* only increases are accumulated */
+ {
+ L_tmp_dB = L_sub(L_XavgL2_fx[i + 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */
+ }
+ L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i]); /* scATHFx[i] is the ATH weight for band i and band i+1 */
+ L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */
+
+ L_Ltot_inc_HF = L_add(L_Ltot_inc_HF, L_tmp); /* Q24 */
+ }
+
+ /* verify that an assumed clean sine does not have any odd LF content by thresholding the accumulated LF reverse up tilt */
+
+ L_Ltot_inc_LF = 0; move32();
+ tmp = s_max(0, sub(sineband_ind_low, 1)); /* could also be pointer init */
+ for (i = tmp; i > 0; i--)
+ {
+ L_tmp_dB = 0; move32();
+ if (L_sub(L_Xavg[i - 1], L_Xavg[i]) > 0) /* only increases are accumulated */
+ {
+ L_tmp_dB = L_sub(L_XavgL2_fx[i - 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */
+ }
+ L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i-1]); /* scATHFx[i-1] is the ATH weight in between band i-1 and band i */
+ L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */
+ L_Ltot_inc_LF = L_add(L_Ltot_inc_LF, L_tmp); /* Q24 */
+ }
+
+ if (L_sub(L_Ltot_inc_HF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */
+ {
+ /* 4.5 dB in log2 is 0.7474 */
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x10); /* still not a pure tone, too great HF side increase */
+ }
+
+ if (L_sub(L_Ltot_inc_LF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */
+ {
+ /* 4.5 dB in log2 is 0.7474 */
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x20); /* still not a pure tone, too great HF side increase */
+ }
+
+ /* verify that an assumed clean sine does not have any odd LF+HF content by thresholding the accumulated LF+HF unexpected tilt */
+ if (L_sub(L_add_sat(L_Ltot_inc_LF, L_Ltot_inc_HF), LFHF_LIM) > 0) /* side_lim=round(Q24x*0.7474) */
+ {
+ /* 6.0 dB in log2 is 0.996578428 */
+ nonpure_tone_detect = s_or(nonpure_tone_detect, 0x40); /* still not a pure tone, too great LF+HF side increase */
+ }
+
+ } /* bands available*/
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ return nonpure_tone_detect;
+ }
+#endif /* CR8_A_PLC_FADEOUT_TUNING plc_phecu_non_pure_ana_fx */
+
+
+
+
diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..50b694e5ca75f16373cb719608419d5b7956eb9d
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c
@@ -0,0 +1,202 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void plc_phEcu_LF_peak_analysis_fx(Word16 * plocs, /* i/o 0 ... Lprot/2 +1*/
+ Word16 * n_plocs, /* i/o 0.. MAX_PLOCS */
+ Word32 * L_f0estQ16, /* i/o Q16*/
+ const Word16 *mag, /* i: Qx */
+ const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15,
+ const Word16 nSubm, Word16 maxPlocs,
+ Word8 *scratchBuffer /* Size = 6 * MAX_PLOCS + 42 */
+)
+
+{
+ Counter i, j;
+ Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag;
+
+ Word32 L_fQ7, *L_f0est_prelQ16;
+ Word16 num_prel = 0, *plocs_prel;
+ Word16 prel_low, prel_high, start, fin;
+ Word16 *plocs_old;
+ Word32 *L_plocsi_old;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_phEcu_LF_peak_analysis_fx", sizeof(struct {
+ Counter i, j;
+ Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag;
+ Word32 L_fQ7, *L_f0est_prelQ16;
+ Word16 num_prel, *plocs_prel;
+ Word16 prel_low, prel_high, start, fin;
+ Word16 *plocs_old;
+ Word32 *L_plocsi_old;
+ }));
+#endif
+
+
+
+ L_f0est_prelQ16 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 7 */
+ plocs_prel = (Word16 *)scratchAlign(L_f0est_prelQ16, sizeof(*L_f0est_prelQ16) * 7); /* Size = 2 * 7 */
+ plocs_old = (Word16 *)scratchAlign(plocs_prel, sizeof(*plocs_prel) * 7); /* Size = 2 * MAX_PLOCS */
+ L_plocsi_old = (Word32 *)scratchAlign(plocs_old, sizeof(*plocs_old) * maxPlocs); /* Size = 4 * MAX_PLOCS */
+
+ test(); test();
+ IF ((*n_plocs > 0) && sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0 &&
+ sub(stPhECU_f0hzLtpBinQ7, (Word16)(2.75 * 128.0)) < 0)
+ {
+
+ /* % analyze/apply f0Ltp to avoid intermodulation effects below f0 of ~180 Hz
+ % we only do the f0Ltp-replacement(s) if there is already an established
+ % fft peak in the region ~fRes to 2.5*fres
+ fft_peak_eval_plocs = 1:3;
+ plocsIntersectFlag = intersect(plocs, fft_peak_eval_plocs ); % check for 1,2,3 in plocs */
+
+ plocsIntersectFlag = 0; move16();
+ peakLF_Xval = 0; move16();
+ n_plocs_ana = s_min(*n_plocs, 3);
+ FOR (i = 0; i < n_plocs_ana; i++)
+ {
+ tmp = plocs[i]; move16();
+ if (sub(tmp, 2) <= 0) /* C index 0, 1,2 checked , [DC, 62.5 Hz, 125Hz ] */
+ {
+ plocsIntersectFlag = add(i, 1);
+ }
+ peakLF_Xval = s_max(mag[tmp], peakLF_Xval);
+ }
+
+ num_prel = 0; move16();
+ IF (plocsIntersectFlag != 0)
+ { /* fft-peak at 0, 62 or 125 Hz */
+ /* analyze if ltp-based f0 need to be added or not */
+ peakLF_Xval = mult_r(peakLF_Xval, (Word16)(.375 * 32768.0)); /* now as a limit */
+
+ FOR (i = 1; i <= nSubm; i++)
+ {
+ L_fQ7 = L_mult0(i, stPhECU_f0hzLtpBinQ7); /* fractional index stored in L_plocsi */
+ f_abs_ind = L_shr_pos(L_add(L_fQ7, 64), 7); /* integer bin index stored in plocs */
+
+ test();
+ IF ((L_sub(L_fQ7, 819) <= 0) && /* % only apply up to ~400hz , 819 = 400/62.5*128 */
+ (sub(mag[f_abs_ind], peakLF_Xval) >
+ 0)) /* % only set as preliminary if relative peak strength is signficant*/
+ {
+ L_f0est_prelQ16[num_prel] = L_shl_pos(L_fQ7, 9); move32();
+ plocs_prel[num_prel] = f_abs_ind; move16();
+ num_prel = add(num_prel, 1);
+ }
+ }
+ } /*intersectFlag*/
+
+ /* now replace/ merge new preliminary added peaks with existing plocs and L_f0estQ16 */
+ /* note that a previous fake/merged magnitude-determined peak may be replaced by two separated side peaks */
+
+ /* a general non-optimized list-merging solution below */
+ test();
+ IF ((num_prel > 0) && (sub(add(num_prel, *n_plocs), MAX_PLOCS) <= 0) /* skip in case plocs list is too large */
+ )
+ {
+ prel_low = plocs_prel[0]; move16();
+ prel_high = plocs_prel[sub(num_prel, 1)]; move16();
+
+ /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */
+ start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */
+
+ FOR (i = sub(*n_plocs, 1); i >= 0; i--)
+ {
+ if (sub(plocs[i], prel_low) >= 0)
+ {
+ start = i; move16();
+ }
+ }
+ start = sub(start, 1); /* end of old section to copy before the added/merged section */
+ start = s_max(start, -1); /* limit for loop later */
+ /*% dbg check low part for a sucessful replace/merge */
+ if (start >= 0 && start < *n_plocs)
+ {
+ ASSERT(plocs[start] < plocs_prel[0]);
+ }
+
+ sub(0, 0);
+ IF (prel_high < plocs[0])
+ {
+ fin = 0; move16(); /*% keep all plocs , just concat */
+ }
+ ELSE
+ {
+ fin = *n_plocs;
+ FOR (i = 0; i < *n_plocs; i++)
+ {
+ sub(0, 0);
+ if (plocs[i] <= prel_high)
+ {
+ fin = i; move16();
+ }
+ }
+ fin = add(fin, 1); /* first element in high part of old plocs to be copied */
+ }
+
+ /*% dbg check high part for a sucessful replace/merge */
+ if (fin >= 0 && fin < *n_plocs)
+ {
+ ASSERT(plocs_prel[sub(num_prel, 1)] < plocs[fin]);
+ }
+
+ /*
+ % actual replace/merge of added integer locations and fractional freqs. into plocs/f0list list ;
+ % three loops in BASOP
+ plocs = [ plocs(1:(start)) ; plocs_prel ; plocs((fin):end) ];
+ f0est = [ f0est(1:(start)) ; f0est_prel; f0est((fin):end) ];
+ */
+
+ FOR (i = 0; i < *n_plocs; i++)
+ {
+ plocs_old[i] = plocs[i]; move16();
+ L_plocsi_old[i] = L_f0estQ16[i]; move32();
+ }
+
+ /*
+ j=0;
+ FOR(i=0; i <= start; i++)
+ {
+ plocs[i] = plocs_old[i]; move16();
+ L_f0estQ16[i] = L_plocsi_old[i]; move32();
+ j++;
+ }
+ */
+
+ j = add(start, 1);
+
+ ASSERT(j>=0);
+
+ FOR (i = 0; i < num_prel; i++) /* NB this section may both insert or overwrite old plocs */
+ {
+ plocs[j] = plocs_prel[i]; move16();
+ L_f0estQ16[j] = L_f0est_prelQ16[i]; move32();
+ j++;
+ }
+ FOR (i = fin; i < *n_plocs; i++) /* copy the tail of the list */
+ {
+ plocs[j] = plocs_old[i]; move16();
+ L_f0estQ16[j] = L_plocsi_old[i]; move32();
+ j++;
+ }
+
+ *n_plocs = j; move16(); /* update total length */
+ } /* num_prel >0*/
+} /* gain/hz Limits */
+
+#ifdef DYNMEM_COUNT
+Dyn_Mem_Out();
+#endif
+
+}
+
+
diff --git a/lib_lc3plus/plc_phecu_peak_locator_fx.c b/lib_lc3plus/plc_phecu_peak_locator_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..531ee8f6fb9724e6e4538f85e300a72a9499d744
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_peak_locator_fx.c
@@ -0,0 +1,385 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+#define RES_fx 1 /* fixed point resolution */
+
+/*-----------------------------------------------------------------------------
+ * peak_locator_fx()
+ *----------------------------------------------------------------------------*/
+void plc_phEcu_peak_locator_fx(const Word16 *inp, /* i: vector with values >=0 ,Qx */
+ const Word16 inp_len, /* i: length of inp */
+ Word16 * int_plocs, /* o: array of filtered integer plocs Q0 */
+ Word16 * n_fsc, /* o: total_ number of filtered located highs Q0 */
+ const Word16 sens, /* i sensitivity, Qx */
+ const Word16 inp_high, /* i global high , Qx */
+ const Word16 inp_low, /* i: global low, Qx */
+ Word16 maxLprot_Red, /* i: optional size for wc memory alloc of scratch buffer */
+ Word8 *scratchBuffer /* i: : scratch buffer 2* 3*(1+1+(maxLprot_Red/2)+1) */
+)
+{
+ Counter j, k, n, idx_high, idx_low;
+ Word16 inp_len_minus1 ;
+ Word16 pairs_start, pairs_end;
+ Word16 *p_tmp;
+ Word16 prev_delta, curr_delta;
+ Word16 delta_predc, delta_fin;
+ Word16 add_dc_flag, add_fin_flag;
+ Word16 low_val_cand_pairs, val_range;
+ Word16 num_pairs, n_tail_values;
+ Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp;
+
+ Word16 cand_high, prev_low;
+ Word16 *sc_idx; /* 1+ 128/2+1, or 1+ 256/2+1 ... 1+ 640/2+1 or 1+ 768/2+1*/
+ Word16 *cand_pairs_buf ; /* actually lowVal + [DC ] + (368/2)pairs + [FS/2] */
+ Word16 *cand_pairs; /* actually [DC ] + pairs + [FS/2] */
+ Word16 * fsc_idx; /* list of high locations in sc__idx 1+368/2+1 */
+
+
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("peak_locator_fx", sizeof(struct {
+ Counter j, k, n, idx_high, idx_low;
+ Word16 inp_len_minus1;
+ Word16 pairs_start, pairs_end;
+ Word16 *p_tmp;
+ Word16 prev_delta, curr_delta;
+ Word16 delta_predc, delta_fin;
+ Word16 add_dc_flag, add_fin_flag;
+ Word16 low_val_cand_pairs, val_range;
+ Word16 num_pairs, n_tail_values;
+ Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp;
+ Word16 cand_high, prev_low;
+ Word16 *sc_idx;
+ Word16 *cand_pairs_buf;
+ Word16 *cand_pairs;
+ Word16 *fsc_idx;
+ }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::peak_locator_fx(1st)");
+#endif
+ sc_idx = (Word16 *)scratchAlign(scratchBuffer, 0); /* ByteSize = 2 * (1+ inp_len+1) */
+ cand_pairs_buf = (Word16 *)scratchAlign(sc_idx, sizeof(*sc_idx) * (1+inp_len+1)); /* ByteSize = 2 * (1+ 1+ inp_len+1 ) */
+ fsc_idx = (Word16 *)scratchAlign(cand_pairs_buf , sizeof(*cand_pairs_buf) * (1+ 1+ inp_len+1)); /* ByteSize = 2 * ( 1+ inp_len + 1) */
+ ASSERT((4 * maxLprot_Red) >= 3 * (1 + 1 + inp_len + 1)); /* basic buffer check */
+ UNUSED(maxLprot_Red);
+
+ inp_len_minus1 = sub(inp_len, 1); /* size of delta=derivative array ,and last index in inp */
+
+ cand_pairs = &cand_pairs_buf[1]; /* ptr init , make space for storing a lowest amplitude value in location -1 */
+ pairs_start = 1; move16(); /* adjusted to zero or 1 or 2 when/if, DC is injected as sc_idx[0], or initial plateau skipped */
+
+ p_tmp = &(sc_idx[pairs_start]); /* ptr init */
+
+
+ /* xor high/low pairs of delta_inp and save sign changes */
+ prev_delta = sub(inp[1], inp[0]); /* precompute very first delta */
+
+ FOR(n = 1; n < inp_len_minus1; n++)
+ { /* sign change analysis */
+ curr_delta = sub(inp[n + 1], inp[n]); /* n+1 ,n , are loop ptrs */
+ if (s_xor(prev_delta, curr_delta) < 0) /* a "0" delta treated as a positive sign */
+ {
+ *p_tmp++ = n; move16(); /* store sign change bin locations , location n in the inp[] signal */
+ }
+ prev_delta = curr_delta; move16();
+ }
+
+ L_sub(0, 0); /* account for length calculaton */
+ k = (Word16)(p_tmp - &(sc_idx[pairs_start]));
+
+
+ /* copy sign change location values to a pairs array */
+ /* leave one initial sc_idx location open for a potential initial DC value */
+
+ ASSERT(pairs_start >= 0 && ((k - 1) + pairs_start) < (inp_len +2));
+ FOR(j = 0; j < k; j++)
+ {
+ cand_pairs[j + pairs_start] = inp[sc_idx[j + pairs_start]]; move16(); move16(); /* the indirect should be calculated */
+ }
+
+
+ /* filter away a potential single initial/trailing plateau
+ to enable correct analysis for adding DC or fs/2 bins */
+
+ logic16();
+ IF((sub(k, 2) >= 0) &&
+ (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) == 0))
+ {
+ pairs_start = add(pairs_start, 1);
+ k = sub(k, 1);
+ }
+
+ /* filter away potential single trailing plateu */
+ pairs_end = sub(add(pairs_start,k), 1); /* point to last established sign change element */
+ logic16();
+ if ((sub(k, 2) >= 0) &&
+ (sub(cand_pairs[sub(pairs_end,1)], cand_pairs[pairs_end]) == 0))
+ {
+ k = sub(k, 1);
+ }
+ pairs_end = sub(add(pairs_start,k), 1); /* recalc ptr to last element */
+
+
+ /* conditionally add high/lows on both sides of input (pre_dc or fin) as candidates */
+ add_dc_flag = 0; move16();
+ add_fin_flag = 0; move16();
+
+
+ IF(sub(k, 1) == 0) /* one single sign change found special case */
+ {
+ if (sub(inp[0], cand_pairs[pairs_start]) != 0)
+ {
+ add_dc_flag = 1; move16(); /* not plateau */
+ }
+
+ if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) != 0)
+ {
+ add_fin_flag = 1; move16(); /* not plateau */
+ }
+ }
+
+ IF(sub(k, 2) >= 0)
+ {
+ delta_predc = sub(cand_pairs[pairs_start + 1], cand_pairs[pairs_start]);
+ delta_fin = sub(cand_pairs[pairs_end], cand_pairs[pairs_end - 1]);
+
+ /* plateaus are allowed to be detected by xor sign change,
+ but still not allowed at the start nor at the end */
+
+ add_dc_flag = 1; move16();
+ if (sub(inp[0], cand_pairs[pairs_start]) == 0)
+ {
+ add_dc_flag = 0; move16(); /* plateau down or , plateus up., --> do not add DC */
+ }
+
+ logic16();
+ if ((sub(inp[0], cand_pairs[pairs_start]) < 0) && (delta_predc > 0))
+ {
+ add_dc_flag = -1; move16(); /*UP - up ... replace */
+ }
+ logic16();
+ if ((sub(inp[0], cand_pairs[pairs_start]) > 0) && (delta_predc < 0))
+ {
+ add_dc_flag = -1; move16(); /* DOWN - down ... % replace */
+ }
+
+ add_fin_flag = 1; move16();
+ if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) == 0)
+ {
+ add_fin_flag = 0; move16(); /* up - plateau ... */
+ }
+ logic16();
+ if ((delta_fin > 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) < 0))
+ {
+ add_fin_flag = -1; move16(); /* up - UP ... % replace , hard to hit */
+ }
+ logic16();
+ if ((delta_fin < 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) > 0))
+ {
+ add_fin_flag = -1; move16(); /*down - DOWN ... % replace */
+ }
+
+ }
+
+ IF(add_dc_flag > 0)
+ { /* add DC */
+ pairs_start = sub(pairs_start, 1);
+ cand_pairs[pairs_start] = inp[0]; move16();
+ sc_idx[pairs_start] = 0; move16();
+ ASSERT(pairs_start >= 0 && pairs_start <= 2);
+ k = add(k, 1);
+ }
+ IF(add_dc_flag < 0)
+ { /* -1 --> replace with DC*/
+ cand_pairs[pairs_start] = inp[0]; move16();
+ sc_idx[pairs_start] = 0; move16();
+ ASSERT(pairs_start >=0 && pairs_start <= 2);
+ }
+
+ IF(add_fin_flag > 0)
+ { /* add FS/2 */
+ pairs_end = add(pairs_end, 1);
+ cand_pairs[pairs_end] = inp[inp_len_minus1]; move16();
+ sc_idx[pairs_end] = inp_len_minus1; move16();
+ k = add(k, 1);
+ }
+ IF(add_fin_flag < 0)
+ { /* -1, replace tail with FS/2*/
+ cand_pairs[pairs_end] = inp[inp_len_minus1]; move16();
+ sc_idx[pairs_end] = inp_len_minus1; move16();
+ }
+ /* preliminary cand_pairs now only have highs , lows , no initial/trailing plateaus */
+
+
+ /* we allow the DC/FsBy2 lows to be used as the candidatelLow */
+ low_val_cand_pairs = inp_low; move16();
+ val_range = sub( inp_high, low_val_cand_pairs); /* used to determine if search is useful at all */
+
+ logic16();
+ if ((sub(val_range, RES_fx) < 0) ||
+ (sub( inp_high, sens) < 0))
+ {
+ k = 0; move16();
+ }
+
+ logic16();
+ if ((k == 0) && (sub(val_range, sens) >= 0))
+ {
+ k = 1; move16();
+ }
+
+
+ IF(sub(k, 2) > 0)
+ {
+ /* low, high, low, ... or
+ high, low, high, ...*/
+
+ cand_phase_start = pairs_start; move16(); /*assume first candidate is a high */
+ if (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) < 0)
+ {
+ cand_phase_start = add(pairs_start, 1); /* first is a low, --> skip to next higher cand */
+ }
+
+ /* high, low, high, ... */
+ tmp = k; move16();
+ if (sub(cand_phase_start, pairs_start) != 0)
+ {
+ tmp = sub(tmp, 1);
+ }
+ num_pairs = shr(tmp, 1);
+ n_tail_values = sub(tmp, shl(num_pairs, 1));
+
+ /* filter preliminary sign changes into sensitivity filtered sign changes */
+
+ *n_fsc = 0; move16(); /* counter of filtered fsc_idx */
+ cand_high = low_val_cand_pairs; move16();
+ cand_idx = -1; move16(); /* sentinel location for no high cand found yet. */
+ cand_pairs[-1] = low_val_cand_pairs; move16();
+
+ prev_low = low_val_cand_pairs; move16();
+ prev_low_plus_sens = add(prev_low, sens);
+
+ /* filter loop for high - low sign change pairs */
+ /* idx_high, idx_low are raw pointers into the cand_pairs and sc_idx arrays */
+
+ FOR( idx_high = cand_phase_start; idx_high < (cand_phase_start + 2 * num_pairs); idx_high += 2)
+ {
+ idx_low = idx_high+1; /* loop ptr increase */
+
+ /* new high candidate larger than previous candidate and */
+ /* sensitivity still larger than the the previous low */
+ tmp = s_max(cand_high, prev_low_plus_sens);
+ if(sub(cand_pairs[idx_high], tmp) > 0)
+ {
+ cand_idx = idx_high; move16(); /* enable or shift candidate position fwd */
+ }
+ cand_high = cand_pairs[cand_idx]; move16(); /* NB, cand_pairs[-1] , has the low_val_cand_pairs value stored */
+
+ /* now check the fwd idx_low of the current {high,low} pair */
+ prev_low = s_min(cand_pairs[idx_low], prev_low);
+
+ tmp = sub(cand_high, sens);
+ IF(sub(tmp, cand_pairs[idx_low]) > 0)
+ {
+ /* this low point is now low enough to fix a previous high candidate */
+
+ fsc_idx[*n_fsc] = cand_idx; move16(); /*% add cand high idx -> output idx list*/
+ *n_fsc = add(*n_fsc, 1);
+
+ prev_low = cand_pairs[idx_low]; move16(); /* use this value as new low estimate */
+ cand_idx = -1; move16(); /* no candidate until next pair or tail bin, and pt to lowVal */
+ cand_high = low_val_cand_pairs; move16(); /* enable next candidate to be selected immediately */
+ }
+ prev_low_plus_sens = add(prev_low, sens);
+ } /* { high, low} FOR loop */
+
+ logic16();
+ IF((n_tail_values == 0) && (cand_idx >= 0))
+ {
+ /* no tail low or high value to analyze
+ still may need to lock a non-locked but qualified candidate */
+ fsc_idx[*n_fsc] = cand_idx; move16();
+ *n_fsc = add(*n_fsc, 1);
+ }
+
+
+ /* cand_pairs vector may have a last orphan value */
+ IF(n_tail_values > 0)
+ {
+ /* cand_pairs vector may have a last orphan tail value */
+ /*
+ logic boils down to if (nTailValues > 0) && (cand_pairs(n_end) > tmp)
+ there is a last one trailing high to process
+
+ a) the last high, may be a new high Peak if we have not yet
+ locked the current candidate
+ b) if we have locked the last candidate, the last high may also be
+ a highpeak if it is high enough from the(newly set previous) valley floor.
+
+ tmp=a||b
+ */
+
+ tmp = s_max(cand_high, prev_low_plus_sens);
+ tmp = sub(cand_pairs[pairs_end], tmp);
+ IF(tmp > 0)
+ {
+ fsc_idx[*n_fsc] = pairs_end; move16();
+ *n_fsc = add(*n_fsc, 1);
+ }
+ ELSE
+ {
+ IF(cand_idx >= 0)
+ { /* we have a previously established high candidate */
+ fsc_idx[*n_fsc] = cand_idx; move16();
+ *n_fsc = add(*n_fsc, 1);
+ }
+
+ }
+ }
+ /* move high locations info from fsc_idx , to output */
+ FOR(j = 0; j < *n_fsc; j++)
+ {
+ ASSERT(fsc_idx[j] >= 0 && fsc_idx[j] < (inp_len+2));
+ int_plocs[j] = sc_idx[fsc_idx[j]]; move16(); move16(); /* the indirect moves are calculated */
+ }
+
+ } /* end of pairs + [tail] section filtering */
+ ELSE
+ {
+ /* constant/single rise or constant decay or very low overall values, cases */
+ *n_fsc = 0; move16();
+
+ logic16();
+ tmp = sub(inp_high, sens);
+ IF((k != 0) && (sub(tmp, low_val_cand_pairs) > 0))
+ {
+ /* low,high */
+ /* high,low */
+ tmp = plc_phEcu_find_ind_fx(inp, inp_len, inp_high); move16();
+ int_plocs[0] = tmp; move16(); /* simply locate the high peak*/
+ *n_fsc = 1; move16();
+ if (tmp < 0)
+ { /*safety in case max value index was not found */
+ *n_fsc = 0; move16();
+ }
+ }
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
diff --git a/lib_lc3plus/plc_phecu_setf0hz_fx.c b/lib_lc3plus/plc_phecu_setf0hz_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..6fffe632c4e29a10eb390166d1d8532661091634
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_setf0hz_fx.c
@@ -0,0 +1,60 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+/*
+st_PhECU_f0minLtp=55; % 55.4 Hz
+st_PhECU_f0maxLtp=376; % 376.4706 Hz
+
+*/
+
+
+Word16
+plc_phEcuSetF0Hz_fx(/* output Q7 bin frequency [0.. 255.xxxx] "1 sign, 8 bits mantissa, 7 binomial" [0-255.9999] */
+ Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr)
+{
+ Word16 pitch_lagQ2, result, expo;
+ Word32 L_result, L_tmp;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_phEcuSetF0Hz_fx", sizeof(struct {
+ Word16 pitch_lagQ2, result, expo;
+ Word32 L_result, L_tmp;
+ Word16 num_FsByResQ0[5];
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::plc_phEcuSetF0Hz_fx");
+#endif
+
+ result = 0; move16();
+ IF (old_pitch_int != 0)
+ {
+ pitch_lagQ2 = add(
+ old_pitch_fr,
+ shl(old_pitch_int, 2)); /* lag at the current fs_idx , max lag_value is is 228(+.75)*48/12.8 = 858 in Q0 */
+
+ L_result = plc_phEcu_ratio_fx(L_deposit_h(num_FsByResQ0[fs_idx]), L_deposit_h(pitch_lagQ2), &expo);
+ L_tmp = L_shl_sat(L_result, sub(11, expo)); /* move to Q7, in high word to allow round*/
+ result = round_fx(L_tmp);
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ return result; /*Q7*/
+}
+
+
diff --git a/lib_lc3plus/plc_phecu_tools_fx.c b/lib_lc3plus/plc_phecu_tools_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..13e90fa4976d3c63c565868b059bf0813fab7805
--- /dev/null
+++ b/lib_lc3plus/plc_phecu_tools_fx.c
@@ -0,0 +1,247 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+/* initilize a short vector */
+void plc_phEcu_initWord16(Word16 * vec, /*i/o : short vector pointer */
+ const Word16 value, /*i : short initialization value */
+ const Word16 len) /*i : number of elements */
+{
+ Counter n;
+
+ FOR (n = 0; n < len; n++)
+ {
+ vec[n] = value; move16();
+ }
+}
+
+/* scale inplace with allowed saturation in upscaling , function not available in basop_util */
+void Scale_sig_sat(Word16 x[], /* i/o: signal to scale Qx */
+ const Word16 lg, /* i : size of x[] Q0 */
+ const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
+)
+{
+ Counter i;
+ Word16 tmp;
+ IF (exp0 > 0)
+ {
+ FOR (i = 0; i < lg; i++)
+ {
+ x[i] = shl_sat(x[i], exp0); move16(); /* no saturation warnings triggered here */
+ }
+ return;
+ }
+ IF (exp0 < 0)
+ {
+ tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */
+ FOR (i = 0; i < lg; i++)
+ {
+ x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */
+ }
+ return;
+ }
+}
+
+void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */
+ const Word16 len, /* i : length */
+ Word16 *minvalPtr /* o : min value Ptr */
+)
+{
+ Word16 minTmp;
+ Counter pos;
+
+ minTmp = inp[0]; move16();
+ assert(len>1);
+ FOR (pos = 1; pos < len; pos++)
+ {
+ minTmp = s_min(inp[pos], minTmp);
+ }
+
+ *minvalPtr = minTmp; move16();
+}
+
+void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */
+ const Word16 len, /* i : length */
+ Word16 *maxvalPtr /* o : *maxvalPtr */
+)
+{
+ Word16 maxTmp;
+ Counter pos;
+
+ maxTmp = inp[0]; move16();
+
+ assert(len>1);
+ FOR (pos = 1; pos < len; pos++)
+ {
+ maxTmp = s_max(inp[pos], maxTmp);
+ }
+ *maxvalPtr = maxTmp; move16();
+}
+
+/* in case a value (e.g max or min) is already known , find the first corresponding array index */
+Word16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */
+ const Word16 *inp, /* i : vector */
+ const Word16 len, /* i : length */
+ const Word16 val /* i : value to find */
+)
+{
+ Word16 val_ind;
+ Counter pos;
+
+ val_ind = -1; move16();
+
+ FOR(pos = 0; pos < len; pos++)
+ {
+ if (sub(inp[pos], val) == 0)
+ {
+ val_ind = pos; move16();
+ }
+ }
+ return val_ind;
+}
+
+/*-----------------------------------------------------------------------------
+ * ratio_fx()
+ *
+ * Divide the numerator by the denominator.
+ *----------------------------------------------------------------------------*/
+Word16 plc_phEcu_ratio_fx( /* o : quotient in Q14 */
+ const Word32 numer, /* i : numerator */
+ const Word32 denom, /* i : denominator */
+ Word16 *expo) /* o : req shift of quotient */
+{
+ Word16 expNumer, expDenom;
+ Word16 manNumer, manDenom;
+ Word16 quotient;
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_phEcu_ratio_fx", sizeof(struct {
+ Word16 expNumer, expDenom;
+ Word16 manNumer, manDenom;
+ Word16 quotient;
+ }));
+#endif
+
+ expDenom = norm_l(denom); /* exponent */
+ manDenom = extract_h(L_shl(denom, expDenom)); /* mantissa */
+ expNumer = norm_l(numer); /* exponent */
+ manNumer = extract_h(L_shl(numer, expNumer)); /* mantissa */
+ manNumer = shr_pos(manNumer, 1); /* Ensure the numerator < the denominator */
+ quotient = div_s(manNumer, manDenom); /* in Q14 */
+
+ *expo = sub(expNumer, expDenom);
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return quotient; /* Q14 */
+}
+
+Word32 winEnCalc( /* o: output summed energy Ltot */
+ const Word16 *x, /* i: Input signal */
+ const Word16 headroom_shift, /* i: headroom_shift */
+ const Word16 *win, /* i: left side Window coefficients */
+ const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */
+ const Word16 halfLength, /* i: Half of the total length of a complete Hamming window. */
+ Word16 *exp /* i/o : i exp of Word16 variable x , o:Lexp of output Word32 sum */
+ )
+{
+ Counter i;
+ Word32 L_tot;
+ const Word16 *pX, *pW;
+ Word16 tmp, tmp_RL;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("PhEcu::GF::winEnCalc", sizeof(struct {
+ Counter i;
+ Word32 L_tot;
+ const Word16 *pX, *pW;
+ Word16 tmp, tmp_RL;
+ }));
+#endif
+
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::winEnCalc");
+#endif
+
+ L_tot = INT32_MAX; move32(); /*acc is on negative side , but as all accumulation is positive, we make use of one extra bit */
+ pX = x;
+ pW = win;
+
+
+ assert( headroom_shift>=0 );
+ FOR (i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */
+ {
+ tmp = mult(*pX++, *pW++);
+ tmp = shr_pos(tmp, headroom_shift); /* shr may/create bias on the negative side , costly options are shr_r or use msu_r */
+ L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative energy side */
+ }
+
+ /* Periodic filter - one more rect sample before end tapering */
+ tmp_RL = add(rectLength, 1);
+ ASSERT(rectLength != 0);
+
+ FOR (i = 0; i < tmp_RL; i++) /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */
+ {
+ tmp = shr_pos( *pX++, headroom_shift);
+ L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative side */
+ }
+
+ tmp_RL = sub(halfLength, 1);
+ ASSERT(rectLength != 0);
+
+ FOR (i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */
+ {
+ tmp = mult(*pX++, *(--pW));
+ tmp = shr_pos(tmp, headroom_shift);
+ L_tot = L_msu0(L_tot, tmp, tmp);
+ }
+
+ /* Lexp = 2*(incoming_exp + dnshift) + 1 , 2x for square + 1(for msu0 DSP dn shift)*/
+ *exp = add(shl_pos(add(*exp, headroom_shift),1),1);
+
+ /* handle wrap on zero point */
+ IF( L_tot >= 0 )
+ { /* L_tot positive --> less than 32 bits needed, */
+ L_tot = L_add(L_tot,(INT32_MIN+1));
+ if( L_tot == 0 )
+ {
+ *exp = LTOT_MIN_EXP; /* WC is actually (-(15+4)*2 + 1 +1 -31) */ ; move16();
+ }
+ L_tot = L_min(L_tot, -1); /* make sure there is energy for future ratio calculations */
+ }
+ ELSE
+ { /* L_tot negative --> more than 31 bits needed for sum , scale 32 bit sum within 31 bits and adjust exp */
+
+ L_tot = L_shr_pos(L_add(L_tot,1),1); /* rnd by adding 1, then use 50% contribution from negative side */
+ L_tot = L_add(L_tot, INT32_MIN>>1); /* add 50% contribution from positive side */
+
+ *exp = add(*exp, 1); move16();
+ }
+
+ L_tot = L_max( -(INT32_MAX), L_tot); /* guard against max accumulation on the negative side , should only occur for rectangle windows */
+ L_tot = L_negate(L_tot); /* no saturation here */
+
+ /* activate when xfp_exp is not used any longer */
+ /* pre-maximize the mantissa for the following steps in burst_ana_dx */
+ tmp = norm_l(L_tot);
+ L_tot = L_shl(L_tot,tmp);
+ *exp = sub(*exp, tmp); move16();
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+ return L_tot;
+}
+
diff --git a/lib_lc3plus/plc_tdac_fx.c b/lib_lc3plus/plc_tdac_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c27cc9e7a29083b56fc54b940870ab8f36b9bc35
--- /dev/null
+++ b/lib_lc3plus/plc_tdac_fx.c
@@ -0,0 +1,217 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+/*
+ * processTdac_fx
+ *
+ * Parameters:
+ * ola_mem o: pointer of output signal Q0
+ * ola_mem_exp o: exponent of output signal Q0
+ * synth i: pointer of input signal Q0
+ * synth_exp i: exponent of input signal Q0
+ * win i: pointer of analysis and synthesis window Q0
+ * la_zeroes i: number of zeroes Q0
+ * frame_len i: frame length Q0
+ *
+ * Function:
+ *
+ *
+ * Returns:
+ * void
+ */
+void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth_inp, const Word16 synth_exp_inp,
+#ifdef ENABLE_HR_MODE
+ const Word32 *win,
+#else
+ const Word16 *win,
+#endif
+ const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer)
+{
+ Counter i;
+ Word16 s;
+ Word16 L;
+ Word16 N;
+ Word16 NZ;
+ Word16 LD2;
+ Word32 sz;
+ Word16 INV_NORM;
+ Word16 INV_NORM_E;
+ Word16 smax;
+ Word16 * synth;
+ Word16 synth_len;
+ Word16 synth_exp;
+#ifdef ENABLE_HR_MODE
+ const Word32 *win1, *win2, *win3, *win4;
+#else
+ const Word16 *win1, *win2, *win3, *win4;
+#endif
+ const Word16 *synth1;
+ const Word16 *synth2;
+ Word16 * ola_mem1;
+ Word16 * ola_mem2;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processTdac_fx", sizeof(struct {
+ Counter i;
+ Word16 s;
+ Word16 L;
+ Word16 N;
+ Word16 NZ;
+ Word16 LD2;
+ Word32 sz;
+ Word16 INV_NORM;
+ Word16 INV_NORM_E;
+ Word16 smax;
+ Word16 * synth;
+ Word16 synth_len;
+ Word16 synth_exp;
+ const Word16 *win1;
+ const Word16 *win2;
+ const Word16 *win3;
+ const Word16 *win4;
+ const Word16 *synth1;
+ const Word16 *synth2;
+ Word16 * ola_mem1;
+ Word16 * ola_mem2;
+ }));
+#endif
+
+ synth = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */
+
+ ASSERT(la_zeroes <= frame_len / 2);
+
+ L = frame_len; move16();
+ LD2 = shr_pos(L, 1);
+ NZ = sub(LD2, la_zeroes);
+
+ /* inverse normalization of sqrt(2/N) inside window */
+#ifdef ENABLE_HR_MODE
+ IF ((sub(frame_len, 960) == 0) || (sub(frame_len, 720) == 0))
+ {
+ INV_NORM = negate(shl_pos(frame_len, (15 - 10)));
+ INV_NORM_E = 3; move16();
+ }
+ ELSE
+#endif
+ {
+ INV_NORM = negate(shl_pos(frame_len, (15 - 9)));
+ INV_NORM_E = 2; move16();
+ if (norm_s(INV_NORM) > 0)
+ {
+ INV_NORM = shl_pos(INV_NORM, 1);
+ INV_NORM_E = 1; move16();
+ }
+ if (sub(frame_len, 120) <= 0)
+ {
+ INV_NORM_E = add(INV_NORM_E, 2);
+ }
+ if (sub(frame_len, 20) <= 0)
+ {
+ INV_NORM_E = add(INV_NORM_E, 2);
+ }
+ }
+
+ /* Scale input */
+ synth_len = sub(shl_pos(L, 1), la_zeroes);
+ s = getScaleFactor16(synth_inp, synth_len);
+
+ FOR (i = 0; i < synth_len; i++)
+ {
+ synth[i] = shl(synth_inp[i], s); move16();
+ }
+ synth_exp = sub(synth_exp_inp, s);
+
+ /* calculate x_ov[L+la_zeroes] ... x_ov[2*L-1] */
+
+ win1 = &win[L + LD2 - 1];
+ win2 = &win[L + LD2];
+
+ win3 = &win[LD2 - 1];
+ win4 = &win[LD2];
+
+ synth1 = &synth[L + LD2 - 1 - la_zeroes];
+ synth2 = &synth[L + LD2 - la_zeroes];
+
+ ola_mem1 = &ola_mem[LD2 - la_zeroes];
+ ola_mem2 = &ola_mem[LD2 - la_zeroes - 1];
+
+ smax = 15; move16();
+
+ FOR (i = 0; i < NZ; i++)
+ {
+ /* analysis windowing + 2N -> N */
+ sz = L_mac_sat(L_mult(*synth1, extractW16(*win1)), *synth2, extractW16(*win2));
+
+ /* N -> 2N + synthesis windowing */
+ *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16();
+ *ola_mem2 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win4))); move16();
+
+ /* determine headroom */
+ s = norm_s(*ola_mem1);
+ if (*ola_mem1 != 0)
+ smax = s_min(smax, s);
+ s = norm_s(*ola_mem2);
+ if (*ola_mem2 != 0)
+ smax = s_min(smax, s);
+
+ /* pointer update */
+ win1--;
+ win2++;
+ win3--;
+ win4++;
+ synth1--;
+ synth2++;
+ ola_mem1++;
+ ola_mem2--;
+ }
+
+ N = LD2; move16();
+
+ FOR (; i < N; i++)
+ {
+ /* analysis windowing + 2N -> N */
+ sz = L_mult(*synth1, extractW16(*win1));
+
+ /* N -> 2N + synthesis windowing */
+ *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16();
+
+ /* determin headroom */
+ s = norm_s(*ola_mem1);
+ if (*ola_mem1 != 0)
+ smax = s_min(smax, s);
+
+ /* pointer update */
+ win1--;
+ win2++;
+ win3--;
+ synth1--;
+ synth2++;
+ ola_mem1++;
+ }
+
+ smax = s_min(smax, 15);
+
+ N = add(N, NZ);
+
+ FOR (i = 0; i < N; i++)
+ {
+ ola_mem[i] = round_fx(L_mult(shl(ola_mem[i], smax), INV_NORM)); move16();
+ }
+
+ *ola_mem_exp = sub(add(synth_exp, INV_NORM_E), smax); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_tdc_inverse_odft_fx.c b/lib_lc3plus/plc_tdc_inverse_odft_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e8e3191c2ef81e074411e5913ca181da7c2277a
--- /dev/null
+++ b/lib_lc3plus/plc_tdc_inverse_odft_fx.c
@@ -0,0 +1,130 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands,
+ Word16 lpc_order, Word8 *scratchBuffer)
+{
+ Counter i;
+ Word16 s;
+ Word16 n_bands2;
+ Word32 * x;
+ const Word32 *inv_odft_twiddle_re;
+ const Word32 *inv_odft_twiddle_im;
+ Word8 * buffer_BASOP_rfftN;
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processInverseODFT_fx", sizeof(struct {
+ Counter i;
+ Word16 s;
+ Word16 n_bands2;
+ Word32 * x;
+ const Word32 *inv_odft_twiddle_re;
+ const Word32 *inv_odft_twiddle_im;
+ Word8 * buffer_BASOP_rfftN;
+ Word32 * params[2];
+ }));
+#endif
+
+ x = scratchAlign(scratchBuffer, 0); /* Size = 320 bytes */
+ buffer_BASOP_rfftN = scratchAlign(x, sizeof(*x) * (MAX_BANDS_NUMBER_PLC + MAX_BANDS_NUMBER_PLC/2)); /* Size = 480 bytes */
+
+ ASSERT(lpc_order <= M);
+ ASSERT(n_bands == 80 || n_bands == 60 || n_bands == 40 || n_bands == 20);
+
+ n_bands2 = shr_pos_pos(n_bands, 1);
+
+ test();
+ IF (sub(n_bands, 20) == 0 || sub(n_bands, 60) == 0)
+ {
+ /* sort input samples */
+ FOR (i = 0; i < n_bands2; i++)
+ {
+ x[2*i] = d2_fx[2 * i]; move32();
+ x[2*i+1] = 0; move32();
+ x[n_bands + 2*i] = d2_fx[n_bands - 1 - 2 * i]; move32();
+ x[n_bands + 2*i + 1] = 0; move32();
+ }
+ BASOP_cfft_lc3plus(&x[0], &x[1], n_bands, 2, &d2_fx_exp, (Word32*)buffer_BASOP_rfftN);
+ }
+ ELSE
+ {
+ /* sort input samples */
+ FOR (i = 0; i < n_bands2; i++)
+ {
+ x[i] = d2_fx[2 * i]; move32();
+ x[n_bands2 + i] = d2_fx[n_bands - 1 - 2 * i]; move32();
+ }
+
+ BASOP_rfftN(x, n_bands, &d2_fx_exp, buffer_BASOP_rfftN);
+ }
+
+ inv_odft_twiddle_re = inv_odft_twiddle_80_re;
+ inv_odft_twiddle_im = inv_odft_twiddle_80_im;
+ IF (sub(n_bands, 20) == 0)
+ {
+ inv_odft_twiddle_re = inv_odft_twiddle_20_re;
+ inv_odft_twiddle_im = inv_odft_twiddle_20_im;
+ }
+ ELSE IF (sub(n_bands, 40) == 0)
+ {
+ inv_odft_twiddle_re = inv_odft_twiddle_40_re;
+ inv_odft_twiddle_im = inv_odft_twiddle_40_im;
+ }
+ ELSE IF (sub(n_bands, 60) == 0)
+ {
+ inv_odft_twiddle_re = inv_odft_twiddle_60_re;
+ inv_odft_twiddle_im = inv_odft_twiddle_60_im;
+ }
+
+ s = norm_l(x[0]);
+
+ /* imag[0] is always zero */
+ r_fx[0] = L_shl_pos(x[0], s); move32();
+
+ /* r_fx[0] = r_fx[0] * 1.0001 */
+ r_fx[0] = Mpy_32_32_lc3plus(r_fx[0], 0x4001A36E); move32();
+ IF (norm_l(r_fx[0]) > 0)
+ {
+ r_fx[0] = L_shl_pos(r_fx[0], 1);
+ }
+ ELSE
+ {
+ s = sub(s, 1);
+ }
+
+ /* post-twiddle */
+ FOR (i = 1; i <= lpc_order; i++)
+ {
+ r_fx[i] = L_add(Mpy_32_32_lc3plus(L_shl(x[2 * i], s), inv_odft_twiddle_re[i - 1]),
+ Mpy_32_32_lc3plus(L_shl(x[2 * i + 1], s), inv_odft_twiddle_im[i - 1])); move32();
+ }
+
+ *r_fx_exp = sub(d2_fx_exp, s); move16();
+
+ /* r_fx[0] must not be zero */
+ IF (r_fx[0] == 0)
+ {
+ r_fx[0] = (Word32)0x7FFFFFFF; move32();
+ FOR (i = 1; i <= lpc_order; i++)
+ {
+ r_fx[i] = 0; move32();
+ }
+ *r_fx_exp = 0; move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_tdc_lagwin_fx.c b/lib_lc3plus/plc_tdc_lagwin_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..e5bd94d66ffb985d19cb1ec48cd4fd3abbd629d0
--- /dev/null
+++ b/lib_lc3plus/plc_tdc_lagwin_fx.c
@@ -0,0 +1,32 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m)
+{
+ /* Start Processing */
+ Counter i;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processLagwin_fx", sizeof(struct { Counter i; }));
+#endif
+
+ FOR (i = 0; i < m; i++)
+ {
+ r[i + 1] = Mpy_32_32_lc3plus(r[i + 1], w[i]); move32();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_tdc_main_fx.c b/lib_lc3plus/plc_tdc_main_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6558dd1b63d0bfad744af76ccdf48ec1c4ddd4b
--- /dev/null
+++ b/lib_lc3plus/plc_tdc_main_fx.c
@@ -0,0 +1,1257 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+/*****************************************************************************/
+
+static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg);
+static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg);
+static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer,
+ const Word16 *hp_filt);
+static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg);
+static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc);
+static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y);
+static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg);
+static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m);
+static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem);
+static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg,
+ const Word16 m);
+static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg);
+
+#ifdef CR8_G_ADD_75MS
+const Word16 beforeNextIncArray_fx[4][4] = {{0,0,0,1},
+ {0,1,0,1},
+ {0,1,1,1},
+ {1,1,1,1}};
+const Word16 nextIncArray_fx[4][4] = {{1,0,0,0},
+ {1,0,1,0},
+ {1,0,1,1},
+ {1,1,1,1}};
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms);
+static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest);
+#endif
+
+/*****************************************************************************/
+
+
+/*
+ * processTimeDomainConcealment_Apply_fx
+ *
+ * Parameters:
+ * pitch_int i : integer pitch lag Q0
+ * preemphFac_fx i : preemphase factor Q15
+ * A_fx i : lp filter coefficients Qx
+ * pcmbufHist_fx i : pointer to input signal Qq_fx_old_exp
+ * frame_length i : frame length Q0
+ * fs_idx i : sample rate index Q0
+ * nbLostFramesInRow i : number of consecutive lost frames Q0
+ * overlap i : overlap length Q0
+ * stabFac_fx i : stability factor Q15
+ * fract i/o: fraction of lag Q0
+ * seed_fx i/o: pointer to seed Q0
+ * gain_p_fx i/o: pointer to gainp Q15
+ * gain_c_fx i/o: pointer to gainc 15Q16
+ * synth_fx o : pointer to synthesized signal Q_syn
+ * Q_syn o : exponent for synthesized signal Q0
+ * alpha o : damping factor Q15
+ * scratchBuffer i : scratch buffer
+ *
+ * Function:
+ * Perform the time domain concealment.
+ *
+ * Returns:
+ * void
+ */
+void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx,
+ const Word16 lpc_order, const Word16 *pcmbufHist_fx, const Word16 frame_length,
+ const Word16 frame_dms, const Word16 fs_idx, const Word16 nbLostFramesInRow,
+ const Word16 overlap, const Word16 stabFac_fx, Word16 *fract,
+ Word16 *seed_fx,
+ Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn, Word16 *alpha, Word16 max_len_pcm_plc,
+ Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q,
+ Word8 *scratchBuffer
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+ ,UWord8 plc_fadeout_type
+#endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ ,Word16 * alpha_type_2_table
+#endif
+)
+{
+ Counter i;
+ Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc;
+ Word32 tmp32, tmp32_2, gainc_tmp;
+ Word16 gain_p_fx;
+ Word32 gain_c_32_fx;
+ Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp;
+ Word16 hpBlendFac;
+ Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph;
+ Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx;
+ Word16 * harmonicBufPtr;
+ Word16 Q_exc = 0, exp_scale;
+ const Word16 *hp_filt_fx, *TDC_high_harm;
+ Word16 alphaPrev_fx;
+ Word16 throttle;
+#ifdef CR8_G_ADD_75MS
+ Word16 frame_dms_idx, nbLostFramesInRow_mod;
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processTimeDomainConcealment_Apply_fx", sizeof(struct {
+ Counter i;
+ Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc;
+ Word32 tmp32, tmp32_2, gainc_tmp;
+ Word16 gain_p_fx;
+ Word32 gain_c_32_fx;
+ Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp;
+ Word16 hpBlendFac;
+ Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph;
+ Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx;
+ Word16 * harmonicBufPtr;
+ Word16 Q_exc, exp_scale;
+ const Word16 *hp_filt_fx, *TDC_high_harm;
+ Word16 alphaPrev_fx;
+ Word16 throttle;
+ Word16 frame_dms_idx, nbLostFramesInRow_mod;
+ }));
+#endif
+
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+ Word32 plc_fadeout_len = 0;
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ if (plc_fadeout_type >= 1){
+#else
+ if (plc_fadeout_type == 1){
+#endif
+ plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS;
+ }
+ else{
+ plc_fadeout_len = PLC_FADEOUT_IN_MS;
+ }
+#endif
+
+ /* len of output signal */
+ len = add(frame_length, overlap);
+
+#ifdef CR8_G_ADD_75MS
+ nbLostFramesInRow_mod = sub(nbLostFramesInRow, 1) & 0x0003;
+
+ frame_dms_idx = mult(frame_dms, 0x051F);
+ nbLostCmpt_loc = add(shr(L_mult0(frame_dms_idx, sub(nbLostFramesInRow, 1)), 2), 1);
+ frame_dms_idx = sub(frame_dms_idx, 1);
+ beforeNextInc = beforeNextIncArray_fx[frame_dms_idx][nbLostFramesInRow_mod]; move16();
+ nextInc = nextIncArray_fx [frame_dms_idx][nbLostFramesInRow_mod]; move16();
+#else
+ nbLostCmpt_loc = nbLostFramesInRow; move16();
+ nextInc = 1; move16();
+ beforeNextInc = 1; move16();
+ SWITCH (frame_dms)
+ {
+ case 25:
+ nbLostCmpt_loc = shr(add(nbLostFramesInRow, 3), 2);
+ nextInc = (nbLostFramesInRow & 0x0003) == 1; move16();
+ beforeNextInc = (nbLostFramesInRow & 0x0003) == 0; move16();
+ BREAK;
+ case 50:
+ nbLostCmpt_loc = shr(add(nbLostFramesInRow, 1), 1);
+ nextInc = (nbLostFramesInRow & 0x0001) == 1; move16();
+ beforeNextInc = (nbLostFramesInRow & 0x0001) == 0; move16();
+ BREAK;
+ }
+#endif
+
+#ifdef CR9_I_INC_TDC_FADEOUT_LEN
+ IF (sub(nbLostCmpt_loc, plc_fadeout_len / 10) > 0)
+#else
+ IF (sub(nbLostCmpt_loc, PLC_FADEOUT_IN_MS / 10) > 0)
+#endif
+ {
+ gain_p_fx = 0; move16();
+ *gain_c_fx = 0; move32();
+ *Q_syn = 0; move16();
+ *alpha = 0; move16();
+ basop_memset(synth_fx, 0, len * sizeof(Word16));
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return;
+ }
+
+ frame_length_2 = shr_pos(frame_length, 1);
+
+ Tc = pitch_int; move16();
+ if (sub(*fract, 0) > 0)
+ {
+ Tc = add(Tc, 1);
+ }
+
+ len_pi_lf_2 = add(Tc, frame_length_2);
+
+ /*----------------------------------------------------------------
+ * Buffer Initialization
+ *
+ * exc_fx synth_mem_fx
+ * |--exc_buf_past--|--exc_buf_curr--|--syn_mem--|--x_pre--|
+ * |--exc2--|
+ * |--syn--|
+ *
+ *---------------------------------------------------------------*/
+
+ /* pointer inits */
+ exc_fx = (Word16 *)scratchAlign(scratchBuffer,
+ sizeof(Word16) * len_pi_lf_2); /* MAX_PITCH+MAX_LEN/2 + MAX_LEN+MDCT_MEM_LEN_MAX */
+ synth_mem_fx = (Word16 *)scratchAlign(exc_fx, sizeof(*exc_fx) * len); /* M */
+ x_pre_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_PITCH+MAX_LEN/2+M+1 */
+ exc2_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX+TDC_L_FIR_HP-1 */
+ synth_tmp_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX */
+ /* Buffers 'overlap' since they are not used at the same time */
+
+ /*---------------------------------------------------------------*
+ * LPC Residual *
+ *---------------------------------------------------------------*/
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+
+ /* copy buffer to pre-emphasis buffer */
+ cnt = add(len_pi_lf_2, lpc_order + 1);
+ basop_memmove(&x_pre_fx[0], &pcmbufHist_fx[max_len_pcm_plc - cnt], cnt * sizeof(Word16));
+
+ /* apply pre-emphasis to the signal; x_pre = x_pre_flt * 2^(q_fx_old_exp-15-Q_exc+1) */
+ Q_exc = TDC_preemph(&(x_pre_fx[1]), preemphFac_fx, sub(cnt, 1));
+
+ /* copy memory for LPC synth */
+ basop_memmove(&synth_mem_fx[0], &x_pre_fx[len_pi_lf_2 + 1], lpc_order * sizeof(Word16));
+
+ /* LPC Residual; exc = exc_fx * 2^(q_fx_old_exp-15-Q_exc) */
+ TDC_LPC_residu_fx(A_fx, &(x_pre_fx[lpc_order + 1]), &(exc_fx[-len_pi_lf_2]), len_pi_lf_2, lpc_order);
+ }
+
+ /*---------------------------------------------------------------*
+ * Calculate gains *
+ *---------------------------------------------------------------*/
+
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+ IF (sub(pitch_int, Tc) == 0)
+ {
+ gain_p_fx =
+ round_fx_sat(L_shl_sat(TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2), 15));
+ }
+ ELSE
+ {
+ tmp32 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 2]), frame_length_2);
+ tmp32_2 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2);
+
+ IF (L_sub(tmp32, tmp32_2) > 0)
+ {
+ Tc = pitch_int; move16();
+ gain_p_fx = round_fx_sat(L_shl_sat(tmp32, 15));
+ *fract = 0; move16();
+ }
+ ELSE
+ {
+ gain_p_fx = round_fx_sat(L_shl_sat(tmp32_2, 15));
+ }
+ }
+
+ if (gain_p_fx < 0)
+ {
+ gain_p_fx = 0; move16();
+ }
+
+ IF (sub(pitch_int, Tc) == 0)
+ {
+ /* gain_c = gain_c_32_fx * 2^(q_fx_old_exp-31) */
+ TDC_calcGainc(exc_fx, Q_exc, Tc, frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx);
+ }
+ ELSE
+ {
+ TDC_calcGainc(exc_fx, Q_exc, pitch_int, frame_length_2, frame_dms, gain_p_fx, &tmp32);
+ TDC_calcGainc(exc_fx, Q_exc, Tc , frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx);
+
+ gain_c_32_fx = L_min(gain_c_32_fx, tmp32); move32();
+ }
+ }
+ ELSE
+ {
+ gain_c_32_fx = *gain_c_fx; move32();
+ gain_p_fx = *alpha;
+ }
+
+ /*---------------------------------------------------------------*
+ * Damping factor *
+ *---------------------------------------------------------------*/
+
+ alphaPrev_fx = 0x7FFF; move16();
+ IF (sub(nbLostFramesInRow,1) > 0)
+ {
+ alphaPrev_fx = *alpha; move16();
+ }
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ IF (sub(plc_fadeout_type,2) == 0 ){
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ *alpha = alpha_type_2_table[nbLostFramesInRow];
+#else
+ IF (sub(frame_dms,50) == 0){
+ IF (sub(nbLostFramesInRow,30) >= 0){
+ *alpha = 0; move16();
+ } ELSE {
+ *alpha = FADE_OUT_TYPE_2_ALPHA_5MS[nbLostFramesInRow]; move16();
+ }
+ }
+ IF (sub(frame_dms,25) == 0){
+ IF (sub(nbLostFramesInRow,60) >= 0){
+ *alpha = 0; move16();
+ } ELSE {
+ *alpha = FADE_OUT_TYPE_2_ALPHA_2_5MS[nbLostFramesInRow]; move16();
+ }
+ }
+#endif
+ }
+ ELSE{
+#endif
+ IF (nextInc != 0)
+ {
+ IF (sub(nbLostCmpt_loc, 1) == 0)
+ {
+ /* Threshold 31470 is 0.98^2 in Q15 format */
+ IF (sub(gain_p_fx, 31470) > 0)
+ {
+ *alpha = 0x7D71; /*0.98f*/
+ move16();
+ }
+ /* Threshold 28037 is 0.925^2 in Q15 format */
+ ELSE IF (sub(gain_p_fx, 28037) < 0)
+ {
+ *alpha = 0x7666; /*0.925f*/
+ move16();
+ }
+ ELSE
+ {
+ exp_scale = 0;
+ *alpha = Sqrt16_lc3plus(gain_p_fx, &exp_scale); move16();
+ *alpha = shl(*alpha, exp_scale);
+ }
+ }
+ ELSE
+ {
+ SWITCH (nbLostCmpt_loc)
+ {
+ case 2:
+ c1 = 0x50A4; /*0.630f*/
+ move16();
+ c2 = 0x2CCD; /*0.350f*/
+ move16();
+ BREAK;
+ default:
+ c1 = 0x5375; /*0.652f*/
+ move16();
+ c2 = 0x29FC; /*0.328f*/
+ move16();
+ BREAK;
+ }
+
+ *alpha = mult_r(stabFac_fx, c2);
+ *alpha = add(*alpha, c1);
+
+ *alpha = mult(gain_p_fx, *alpha);
+
+
+ IF (sub(nbLostCmpt_loc, 2) == 0)
+ {
+ if (sub(*alpha, 0x75A2 /*0.919f*/) < 0)
+ {
+ *alpha = 0x75A2; move16();
+ }
+ }
+ ELSE IF (sub(nbLostCmpt_loc, 5) > 0)
+ {
+ gain_p_fx = *alpha; move16();
+ }
+ }
+ }
+
+ IF (sub(nbLostCmpt_loc,3) > 0)
+ {
+ SWITCH (frame_dms)
+ {
+ case 25: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK;
+#ifdef CR9_J_SLOW_TDC_FADEOUT
+ case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK;
+#else
+ case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_050_FX); BREAK;
+#endif
+#ifdef CR8_G_ADD_75MS
+ case 75: *alpha = mult(*alpha, PLC34_ATTEN_FAC_075_FX); BREAK;
+#endif
+ case 100: *alpha = mult(*alpha, PLC34_ATTEN_FAC_100_FX); BREAK;
+ }
+ }
+ if (sub(nbLostCmpt_loc, 5) > 0)
+ {
+ gain_p_fx = *alpha; move16();
+ }
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ }
+#endif
+
+ /*---------------------------------------------------------------*
+ * Construct the harmonic part *
+ * Last pitch cycle of the previous frame is repeatedly copied. *
+ *---------------------------------------------------------------*/
+
+ pt_exc = harmonicBuf_fx; move16();
+ pt1_exc = exc_fx - Tc; move16();
+ s = s_min(len, Tc); move16();
+ test();
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+ *harmonicBuf_Q = Q_exc; move16();
+ IF (sub(stabFac_fx, 32767 /*1.f Q15*/) >= 0)
+ {
+ basop_memmove(pt_exc, pt1_exc, Tc * sizeof(Word16));
+ }
+ ELSE
+ {
+ /* These values are necessary for the last five filtered samples */
+ basop_memmove(exc_fx, &exc_fx[-Tc], (TDC_L_FIR_HP-1)/2 * sizeof(Word16));
+ TDC_high_harm = TDC_high_32_harm;
+ if (sub(fs_idx, 1) <= 0)
+ {
+ TDC_high_harm = TDC_high_16_harm;
+ }
+ FOR (i = 0; i < Tc; i++)
+ {
+ pt_exc[i] = TDC_Dot_product(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], TDC_high_harm, TDC_L_FIR_HP);
+ }
+ }
+ }
+ ELSE
+ {
+ Q_exc = *harmonicBuf_Q; move16();
+ }
+
+
+ /*---------------------------------------------------------------*
+ * Construct the random part of excitation *
+ *---------------------------------------------------------------*/
+
+ TDC_random_fx(seed_fx, add(len, sub(TDC_L_FIR_HP, 1)), exc2_fx);
+
+ /* high pass noise */
+ hp_filt_fx = TDC_high_32;
+ if (sub(fs_idx, 1) <= 0)
+ {
+ hp_filt_fx = TDC_high_16;
+ }
+
+ IF (sub(nbLostFramesInRow, 1) == 0)
+ {
+ TDC_highPassFiltering_fx(len, exc2_fx, TDC_L_FIR_HP, hp_filt_fx);
+ }
+ ELSE
+ {
+ throttle = div_s(nbLostCmpt_loc, add(nbLostCmpt_loc, PLC3_HPBLENDTHROTTLE));
+ hpBlendFac = mult(sub(0x7FFF, *alpha), throttle);
+ c1 = sub(0x7FFF, hpBlendFac);
+ FOR (i = 0; i < len; i++)
+ {
+ /* Return value of dot product is Q1 */
+ tmp32 = Mpy_32_16_lc3plus(TDC_L_Dot_product(&exc2_fx[i], hp_filt_fx, TDC_L_FIR_HP), c1 /*Q15*/);
+ exc2_fx[i] = round_fx(L_mac0(tmp32, hpBlendFac, exc2_fx[i+TDC_L_FIR_HP/2])); move16();
+ }
+ }
+
+ /* normalize energy */
+ TDC_normalize_energy_fx(&gain_inov_fx, &gain_inov_fx_exp, exc2_fx, frame_length);
+ tmp32 = Mpy_32_16_lc3plus(
+ L_sub(590558016l /*1.1 Q29*/, Mpy_32_16_lc3plus(L_shr_pos(L_deposit_h(gain_p_fx), 2), 24576 /*0.75*/)) /*Q29*/,
+ gain_inov_fx /*Q15,gain_inov_e*/); /*Q29,gain_inov_e*/
+ s = norm_l(tmp32);
+ tmp32 = L_shl_pos(tmp32, s);
+ tmp32 = L_min(tmp32, 0x7FFEFFFF);
+ gain_inov_fx_exp = add(sub(gain_inov_fx_exp, s), 31 - 29); /*->Q31*/
+ gain_inov_fx = round_fx(tmp32); /*Q15,gain_inov_e*/
+
+ /* gains */
+ gain_h_fx = alphaPrev_fx; move16();
+
+ /* update steps */
+ if (frame_length == 720)
+ {
+ ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, 960, &ilen_exp);
+ } else {
+ ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, frame_length, &ilen_exp);
+ }
+ step_fx = round_fx(L_shl(L_mult(sub(gain_h_fx, *alpha), ilen), ilen_exp));
+
+ s = norm_l(gain_c_32_fx);
+ tmp32 = L_shl_pos(gain_c_32_fx, s);
+
+ gain_c_16_fx = extract_h(tmp32);
+ gain_c_16_fx_exp = sub(15, s);
+#ifdef CR9_M_FIX_DIV_ZERO
+ gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, s_max(alphaPrev_fx, 1)));
+#else
+ gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, alphaPrev_fx));
+#endif
+ tmp32 = L_sub (tmp32, gainc_tmp);
+ step_n_fx = round_fx(L_shl(Mpy_32_16_lc3plus(tmp32, ilen), ilen_exp));
+
+ /*---------------------------------------------------------------*
+ * Construct the total excitation *
+ *---------------------------------------------------------------*/
+
+ harmonicBufPtr = harmonicBuf_fx + ((nbLostFramesInRow - 1) * frame_length) % Tc;
+
+ s1 = add(Q_exc, add(gain_inov_fx_exp, gain_c_16_fx_exp));
+ cnt = add(frame_length, TDC_L_FIR_HP / 2);
+
+ g_fx = mult_r(gain_c_16_fx, gain_inov_fx);
+
+ FOR (i = 0; i < len; i++)
+ {
+ /* harmonic */
+ if (harmonicBufPtr - harmonicBuf_fx >= Tc) {
+ harmonicBufPtr = harmonicBuf_fx;
+ }
+ exc_fx[i] = *harmonicBufPtr++;
+ tmp32 = L_mult(exc_fx[i], gain_h_fx);
+ /* random */
+ tmp32_2 = L_shl_sat(L_mult(exc2_fx[i], g_fx), s1);
+ /* total */
+ exc_fx[i] = round_fx_sat(L_add_sat(tmp32, tmp32_2)); move16();
+ /* update */
+ gain_h_fx = s_max(sub(gain_h_fx, step_fx), 0);
+ gain_c_16_fx = s_max(sub(gain_c_16_fx, step_n_fx), 0);
+ g_fx = mult_r(gain_c_16_fx, gain_inov_fx);
+ }
+
+ /* update gain */
+ *gain_c_fx = L_shl(gainc_tmp, sub(gain_c_16_fx_exp, 15)); move32();
+
+
+ /*----------------------------------------------------------*
+ * Compute the synthesis speech *
+ *----------------------------------------------------------*/
+
+ /* introduce some headroom to avoid Overflows, 2 bit seem to be sufficient */
+ *Q_syn = sub(Q_exc, 2);
+ *Q_syn = s_max(*Q_syn, -3);
+
+ exp_scale = sub(*Q_syn, Q_exc - 1);
+
+ IF (sub(nbLostFramesInRow, 1) != 0)
+ {
+ synth_mem_fx = synthHist_fx;
+ }
+ Copy_Scale_sig(synth_mem_fx, &synth_tmp_fx[-lpc_order], lpc_order, exp_scale);
+ TDC_LPC_synthesis_fx(sub(Q_exc, *Q_syn), A_fx, exc_fx, synth_tmp_fx, len, lpc_order);
+
+ FOR (i=0; i= 0);
+ synth_fx[i] = mult(synth_fx[i], gain_h_fx);
+ gain_h_fx = sub(gain_h_fx, step_fx);
+ }
+ basop_memset(&synth_fx[frame_length], 0, overlap * sizeof(Word16));
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
+/*****************************************************************************/
+
+static Word32 syn_kern_2(Word32 L_tmp, const Word16 a[], const Word16 y[])
+{
+ L_tmp = L_msu_sat(L_tmp, y[-1], a[1]);
+ L_tmp = L_msu_sat(L_tmp, y[-2], a[2]);
+ return L_tmp;
+}
+
+static Word32 syn_kern_4(Word32 L_tmp, const Word16 a[], const Word16 y[])
+{
+ L_tmp = syn_kern_2(L_tmp, a, y);
+ return syn_kern_2(L_tmp, a + 2, y - 2);
+}
+
+static Word32 syn_kern_8(Word32 L_tmp, const Word16 a[], const Word16 y[])
+{
+ L_tmp = syn_kern_4(L_tmp, a, y);
+ return syn_kern_4(L_tmp, a + 4, y - 4);
+}
+
+static Word32 syn_kern_16(Word32 L_tmp, const Word16 a[], const Word16 y[])
+{
+ L_tmp = syn_kern_8(L_tmp, a, y);
+ return syn_kern_8(L_tmp, a + 8, y - 8);
+}
+
+/*
+ * TDC_Dot_product
+ *
+ * Parameters:
+ * x i: x vector Q0
+ * y i: y vector Q0
+ * lg i: vector length Q0
+ *
+ * Function:
+ * dot product
+ *
+ * Returns:
+ * dot product Q0
+ */
+static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 sum;
+ );
+
+ sum = L_mult(x[0], y[0]);
+ FOR (i = 1; i < lg-1; i++)
+ {
+ sum = L_mac_sat(sum, x[i], y[i]);
+ }
+
+ sum = mac_r_sat(sum, x[lg-1], y[lg-1]);
+
+ Dyn_Mem_Deluxe_Out();
+
+ return sum;
+}
+
+/*
+ * TDC_L_Dot_product
+ *
+ * Parameters:
+ * x i: x vector Q0
+ * y i: y vector Q0
+ * lg i: vector length Q0
+ *
+ * Function:
+ * dot product
+ *
+ * Returns:
+ * dot product Q1
+ */
+static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 sum;
+ );
+
+ sum = L_mac0(1L, x[0], y[0]);
+ FOR (i = 1; i < lg; i++)
+ {
+ sum = L_mac0(sum, x[i], y[i]);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+
+ return sum;
+}
+
+/*
+ * TDC_highPassFiltering_fx
+ *
+ * Parameters:
+ * L_buffer i: buffer length
+ * exc2 i: unvoiced excitation before the high pass filtering Qx/Qx+1
+ * l_fir_fer i: length highpass filter
+ * hp_filt i: highpass filter coefficients Q15
+ *
+ * Function:
+ * Highpass filter
+ *
+ * Returns:
+ * void
+ */
+static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer,
+ const Word16 *hp_filt)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+
+ FOR (i = 0; i < L_buffer; i++)
+ {
+ exc2[i] = round_fx(L_sub(TDC_L_Dot_product(&exc2[i], hp_filt, l_fir_fer), 1)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*
+ * TDC_calcGainc
+ *
+ * Parameters:
+ * exc i: pointer to excitation buffer
+ * Q_exc i: Q format of excitation buffer
+ * old_fpitch i: pitch_int
+ * lg i: length
+ * lp_gainp i: gain p
+ * lp_gainc o: pointer to gain (15Q16)
+ *
+ * Function:
+ * Gain calculation
+ *
+ * Returns:
+ * void
+ */
+static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 tmp16, tmp_e, tmp2_e;
+ Word32 L_tmp, L_tmp_max;
+ Counter i;
+ );
+
+ L_tmp = L_deposit_l(0);
+
+ FOR (i = 0; i < lg; i++)
+ {
+ /* gain_c += ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ) * ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ); */
+ tmp16 = sub_sat(exc[i - lg] /*Q1*/, mult_r(lp_gainp /*Q15*/, exc[i - lg - old_fpitch] /*Q1*/) /*Q1*/);
+ L_tmp = L_mac0_sat(L_tmp, tmp16, tmp16); /*Q3*/
+ }
+
+ IF (sub(frame_dms, 100) < 0)
+ {
+ L_tmp_max = L_deposit_l(0);
+ FOR (i = 0; i < lg; i++)
+ {
+ L_tmp_max = L_mac0_sat(L_tmp_max, exc[i - lg], exc[i - lg]); /*Q3*/
+ }
+ L_tmp = L_min(L_tmp, L_tmp_max);
+ }
+
+ tmp_e = norm_l(L_tmp);
+ L_tmp = L_shl(L_tmp, tmp_e);
+ tmp_e = sub(sub(31, shl_pos(Q_exc, 1)), tmp_e); /*L_tmp is Q31, now*/
+ tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(L_tmp /*Q31,norm,tmp_e*/, lg /*Q15,15*/, &tmp2_e) /*Q15,tmp2_e+tmp_e-15*/;
+ tmp_e = sub(add(tmp2_e, tmp_e), 15);
+
+ IF (tmp16 != 0)
+ {
+ tmp16 = Sqrt16_lc3plus(tmp16, &tmp_e); /*Q15,norm,tmp_e*/
+ tmp_e = L_min(tmp_e, 15);
+ *lp_gainc = L_shl_pos(L_deposit_l(tmp16), add(tmp_e, 1)); /*15Q16*/
+ move32();
+ }
+ ELSE
+ {
+ *lp_gainc = 0;
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*
+ * TDC_calcGainp
+ *
+ * Parameters:
+ * x i: input signal
+ * y i: shifted input signal
+ * lg i: vector length
+ *
+ * Function:
+ * Gain calculation
+ *
+ * Returns:
+ * gain (15Q16)
+ */
+static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg)
+{
+ Dyn_Mem_Deluxe_In(
+ Word32 tcorr, tener, Lgain, L_tmp1, L_tmp2;
+ Word16 m_corr, m_ener, negative, Q_corr, Q_ener;
+ Counter i;
+ );
+
+ negative = 0; move16();
+
+ L_tmp1 = L_deposit_l(0);
+ L_tmp2 = L_deposit_l(0);
+ FOR (i = 0; i < lg; i += 2)
+ {
+ L_tmp1 = L_mac0_sat(L_tmp1, x[i], y[i]);
+ L_tmp2 = L_mac0_sat(L_tmp2, x[i + 1], y[i + 1]);
+ }
+ tcorr = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1));
+ Q_corr = norm_l(tcorr);
+ tcorr = L_shl(tcorr, Q_corr);
+ Q_corr = sub(2, Q_corr);
+
+ L_tmp1 = L_deposit_l(0);
+ L_tmp2 = L_deposit_l(0);
+ FOR (i = 0; i < lg; i += 2)
+ {
+ L_tmp1 = L_mac0_sat(L_tmp1, y[i], y[i]);
+ L_tmp2 = L_mac0_sat(L_tmp2, y[i + 1], y[i + 1]);
+ }
+ tener = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1));
+ Q_ener = norm_l(tener);
+ tener = L_shl(tener, Q_ener);
+ Q_ener = sub(2, Q_ener);
+
+ tener = L_max(tener, 1);
+
+ if (tcorr <= 0)
+ {
+ negative = 1; move16();
+ }
+ tcorr = L_abs(tcorr);
+
+ m_corr = extract_h(tcorr);
+
+ m_ener = extract_h(tener);
+
+ IF (sub(m_corr, m_ener) > 0)
+ {
+ m_corr = shr_pos(m_corr, 1);
+ Q_corr = add(Q_corr, 1);
+ }
+ if (m_ener == 0)
+ {
+ move16();
+ m_corr = 0x7FFF;
+ }
+ if (m_ener != 0)
+ {
+ m_corr = div_s(m_corr, m_ener);
+ }
+
+ Q_corr = sub(Q_corr, Q_ener);
+
+ Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1));
+
+ if (negative != 0)
+ {
+ Lgain = L_negate(Lgain);
+ }
+
+ Dyn_Mem_Deluxe_Out();
+
+ return Lgain;
+}
+
+/*
+ * TDC_LPC_synthesis_fx
+ *
+ * Parameters:
+ * sh i : scaling to apply for a[0] Q0
+ * a[] i : LP filter coefficients Qx
+ * x[] i : input signal Qx
+ * y[] o : output signal Qx-s
+ * lg i : size of filtering Q0
+ * m i : order of LP filter Q0
+ *
+ * Function:
+ * Apply LP filtering to obtain synthesis signal.
+ * Memory size is always m.
+ *
+ * Returns:
+ * void
+ */
+static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg,
+ const Word16 m)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word16 a0;
+ Word16 q;
+ Word32(*syn_kern)(Word32 L_tmp, const Word16 a[], const Word16 y[]
+ ););
+
+ ASSERT(m == 16 || m == 8);
+
+ if (sub(m, 16) == 0)
+ {
+ syn_kern = syn_kern_16;
+ }
+ if (sub(m, 8) == 0)
+ {
+ syn_kern = syn_kern_8;
+ }
+
+ q = add(norm_s(a[0]), 1);
+ a0 = shr_sat(a[0], sh);
+
+ FOR (i = 0; i < lg; i++)
+ {
+ y[i] = round_fx_sat(L_shl_sat(syn_kern(L_mult(a0, x[i]), a, &y[i]), q)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/* TDC_LPC_residu_fx
+ *
+ * Parameters:
+ * a I: LP filter coefficients (Qx)
+ * x I: input signal
+ * y O: output signal
+ * lg I: size of filtering
+ * m I: lpc order
+ *
+ * Function:
+ * Apply inverse filtering to obtain LP residual signal.
+ *
+ * Returns:
+ * void
+ */
+static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 a_exp;
+ Word32 s;
+ Counter i;
+ );
+
+ ASSERT(m == 16 || m == 8);
+
+ a_exp = add(norm_s(a[0]), 1);
+ a_exp = add(a_exp, 1);
+
+ IF (sub(m, 16) == 0)
+ {
+ FOR (i = 0; i < lg; i++)
+ {
+ s = L_mult(x[i], a[0]);
+ s = L_mac_sat(s, x[i - 1], a[1]);
+ s = L_mac_sat(s, x[i - 2], a[2]);
+ s = L_mac_sat(s, x[i - 3], a[3]);
+ s = L_mac_sat(s, x[i - 4], a[4]);
+ s = L_mac_sat(s, x[i - 5], a[5]);
+ s = L_mac_sat(s, x[i - 6], a[6]);
+ s = L_mac_sat(s, x[i - 7], a[7]);
+ s = L_mac_sat(s, x[i - 8], a[8]);
+ s = L_mac_sat(s, x[i - 9], a[9]);
+ s = L_mac_sat(s, x[i - 10], a[10]);
+ s = L_mac_sat(s, x[i - 11], a[11]);
+ s = L_mac_sat(s, x[i - 12], a[12]);
+ s = L_mac_sat(s, x[i - 13], a[13]);
+ s = L_mac_sat(s, x[i - 14], a[14]);
+ s = L_mac_sat(s, x[i - 15], a[15]);
+ s = L_mac_sat(s, x[i - 16], a[16]);
+
+ s = L_shl_sat(s, a_exp);
+ y[i] = round_fx_sat(s); move16();
+ }
+ }
+ IF (sub(m, 8) == 0)
+ {
+ FOR (i = 0; i < lg; i++)
+ {
+ s = L_mult(x[i], a[0]);
+ s = L_mac_sat(s, x[i - 1], a[1]);
+ s = L_mac_sat(s, x[i - 2], a[2]);
+ s = L_mac_sat(s, x[i - 3], a[3]);
+ s = L_mac_sat(s, x[i - 4], a[4]);
+ s = L_mac_sat(s, x[i - 5], a[5]);
+ s = L_mac_sat(s, x[i - 6], a[6]);
+ s = L_mac_sat(s, x[i - 7], a[7]);
+ s = L_mac_sat(s, x[i - 8], a[8]);
+
+ s = L_shl_sat(s, a_exp);
+ y[i] = round_fx_sat(s); move16();
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/* TDC_random_fx
+ *
+ * Parameters:
+ * seed i/o: seed for random number
+ * lg i : vector length
+ * y o : output values
+ *
+ * Function:
+ * Uniform distributed random generator.
+ *
+ * Returns:
+ * random number
+ */
+static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+
+ FOR (i = 0; i < lg; i++)
+ {
+ *seed = extract_l(L_mac0(16831L, *seed, 12821));
+ *y++ = *seed; move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*
+ * TDC_preemph
+ *
+ * Parameters:
+ * x i/o: signal Qx
+ * fac i: preemphasis factor Q15
+ * lg i: vector length
+ *
+ * Function:
+ * Filtering through 1 - fac z^-1
+ *
+ * Returns:
+ * Q-factor
+ */
+static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 fac_sh, Q_max_value, Q_out;
+ Word32 max_val;
+ Counter i;
+ );
+
+ fac_sh = shr(fac, 3);
+ Q_max_value = 4096; move16();
+ Q_out = 12; move16();
+
+ max_val = 0; move32();
+ FOR (i = sub(lg, 1); i >= 0; i--)
+ {
+ max_val = L_max(L_abs(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh)), max_val);
+ }
+
+ IF (extract_h(max_val) != 0)
+ {
+ Q_out = s_min(s_max(sub(norm_s(extract_h(max_val)), 3), 0), 12);
+ }
+
+ FOR (i = sub(lg, 1); i >= 0; i--)
+ {
+ x[i] = round_fx(L_shl(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh), Q_out)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+
+ return sub(Q_out, 2);
+}
+
+/*
+ * TDC_deemph_fx
+ *
+ * Parameters:
+ * x i: input signal Qx
+ * y o: output signal Qx
+ * fac i: deemphasis factor Q15
+ * lg i: size of filtering Q0
+ * mem i: memory (x[-1])
+ *
+ * Function:
+ * Filtering through 1/(1-fac z^-1)
+ *
+ * Returns:
+ * void
+ */
+static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+
+ y[0] = round_fx_sat(L_mac_sat(L_deposit_h(x[0]), mem, fac)); move16();
+ FOR (i = 1; i < lg; i++)
+ {
+ y[i] = round_fx_sat(L_mac_sat(L_deposit_h(x[i]), y[i - 1], fac)); move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*
+ * TDC_normalize_energy_fx
+ *
+ * Parameters:
+ * gain o: gain
+ * gain_exp o: exponent of gain
+ * x i: input signal
+ * lg i: length of input signal
+ *
+ * Function:
+ * Normalizes the energy.
+ *
+ * Returns:
+ * void
+ */
+static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word16 c;
+ Word16 e;
+ Word16 e1;
+ Word16 e2;
+ Word32 tmp;
+ Word16 tmp16;
+ );
+
+ tmp = 0; move32();
+ FOR (i = 0; i < lg; i++)
+ {
+ tmp16 = mult_r(x[i], 2048);
+ tmp = L_mac(tmp, tmp16, tmp16);
+ }
+
+ e = norm_l(tmp);
+ tmp = L_shl_pos(tmp, e);
+ e1 = sub(sub(30, e), -8); move16();
+ tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(tmp, lg, &e2);
+
+ e = 0; move16();
+ if (tmp16 != 0)
+ {
+ e = sub(add(e1, e2), 15);
+ }
+
+ c = 0x0148; /* 0.01 */
+ move16();
+ IF (e > 0)
+ {
+ c = shr(c, s_min(e, 15));
+ }
+ ELSE
+ {
+ tmp16 = shr(tmp16, s_min(negate(e), 15));
+ e = 0; move16();
+ }
+
+ e2 = 2; move16();
+ if (s_and(e, 1))
+ {
+ e2 = 1; move16();
+ }
+
+ tmp16 = add(shr_pos(tmp16, e2), shr_pos(c, e2));
+ e = add(e, e2);
+
+ tmp16 = Sqrt16_lc3plus(tmp16, &e);
+
+ *gain = BASOP_Util_Divide1616_Scale_lc3plus((Word16)0x7FFF, tmp16, &e1); move16();
+ *gain_exp = sub(e1, e); move16();
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms)
+{
+ Word16 n_help;
+ Word32 n_shift;
+
+ if (nbLostFramesInRow <= 3*(100.0/frame_dms)){
+ n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms;
+ return powWord16rest(31129,n_help/100,n_help%100);
+ }
+ else {
+ n_shift = (nbLostFramesInRow - 3*(100/frame_dms)) * 50/frame_dms;
+ n_help = (n_shift + (100/frame_dms) - 1) * frame_dms;
+ return powWord16rest(22937,n_help/100,n_help%100);
+ }
+}
+
+Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms)
+{
+ Word16 n_help;
+ Word16 selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * (100/frame_dms);
+
+ if (selector >= nbLostFramesInRow){
+ return type_2_alpha_long(nbLostFramesInRow, frame_dms);
+ }
+ else {
+ n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms;
+ return powWord16rest(16383,n_help/100, n_help%100);
+ }
+}
+
+static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest) {
+ Word32 exp_result = 32767;
+ Word32 tmp_result;
+ Word16 root, i, exp2;
+
+ FOR (i = 0; i < exp; ++i) {
+ tmp_result = (Word32)exp_result * base;
+ exp_result = (Word16)(tmp_result >> 15);
+ }
+
+ IF (rest != 0) {
+ exp2 = 0;
+ SWITCH (rest)
+ {
+ case 50:
+ root = Sqrt16_lc3plus(base, &exp2);
+ shr(root,exp2);
+ exp_result = L_shr(exp_result * root,15); /* 0.5^1.5 = 0.5^(3/2) = 0.5^3*sqrt(0.5) */
+ BREAK;
+ case 25:
+ root = Sqrt16_lc3plus(base, &exp2);
+ shr(root,exp2);
+ exp2 = 0;
+ root = Sqrt16_lc3plus(root, &exp2);
+ shr(root,exp2);
+ exp_result = L_shr(exp_result * root,15); /* 0.5^(1/4) = 0.5^sqrt(sqrt(0.5)) */
+ BREAK;
+ case 75:
+ root = Sqrt16_lc3plus(base, &exp2);
+ shr(root,exp2);
+ exp2 = 0;
+ root = Sqrt16_lc3plus(root, &exp2);
+ shr(root,exp2);
+ tmp_result = powWord16rest(root, 3, 0);
+ exp_result = L_shr( exp_result * tmp_result,15);
+ BREAK;
+ }
+ }
+ return (Word16) exp_result;
+}
+#endif
diff --git a/lib_lc3plus/plc_tdc_pre_emphasis_fx.c b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..3a961acf7398235d16b5fc0d6b192076aee2e8ee
--- /dev/null
+++ b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c
@@ -0,0 +1,95 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms, Word8 *scratchBuffer)
+{
+ Word16 s;
+ Word32 nrg;
+ Word16 smax;
+ Counter band;
+ const Word16 *pre_emph;
+ const Word16 *pre_emph_e;
+ Word16 * d2_band_fx_exp;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processPreEmphasis_fx", sizeof(struct {
+ Word16 s;
+ Word32 nrg;
+ Word16 smax;
+ Counter band;
+ const Word16 *pre_emph;
+ const Word16 *pre_emph_e;
+ Word16 * d2_band_fx_exp;
+ }));
+#endif
+
+ d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC = 160 bytes */
+
+ pre_emph = lpc_lin_pre_emphasis[fs_idx];
+ pre_emph_e = lpc_lin_pre_emphasis_e[fs_idx];
+ SWITCH (frame_dms)
+ {
+ case 25:
+ pre_emph = lpc_lin_pre_emphasis_2_5ms[fs_idx];
+ pre_emph_e = lpc_lin_pre_emphasis_e_2_5ms[fs_idx];
+ BREAK;
+ case 50:
+ pre_emph = lpc_lin_pre_emphasis_5ms[fs_idx];
+ pre_emph_e = lpc_lin_pre_emphasis_e_5ms[fs_idx];
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ pre_emph = lpc_lin_pre_emphasis_7_5ms[fs_idx];
+ pre_emph_e = lpc_lin_pre_emphasis_e_7_5ms[fs_idx];
+ BREAK;
+#endif
+ }
+
+ ASSERT(n_bands==20 || n_bands==40 || n_bands==60 || n_bands ==80);
+
+ /* start processing */
+ smax = -31; move16();
+
+ FOR (band = 0; band < n_bands; band++)
+ {
+ nrg = Mpy_32_16_lc3plus(d2_fx[band], pre_emph[band]);
+
+ if (nrg == 0)
+ {
+ s = 31; move16();
+ }
+
+ if (nrg != 0)
+ {
+ s = norm_l(nrg);
+ }
+
+ d2_fx[band] = L_shl_pos(nrg, s); move32();
+ d2_band_fx_exp[band] = sub(pre_emph_e[band], s); move16();
+
+ smax = s_max(smax, d2_band_fx_exp[band]);
+ }
+
+/* Rescale band energies */
+ FOR (band = 0; band < n_bands; band++)
+ {
+ d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31)); move32();
+ }
+ /* Save common exponent for all bands */
+ *d2_fx_exp = add(*d2_fx_exp, smax); move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/plc_update_aft_imdct_fx.c b/lib_lc3plus/plc_update_aft_imdct_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..663f491c9e80970fa3e53839063e792db9642a54
--- /dev/null
+++ b/lib_lc3plus/plc_update_aft_imdct_fx.c
@@ -0,0 +1,343 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac);
+
+void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx,
+ Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[],
+ Word16 *ns_cum_alpha, AplcSetup *plcAd)
+{
+ Word16 oldLen, usedHistlen;
+ Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new;
+ Word16 frontLen, pastLen;
+ Word16 marginOldPast;
+ Word16 marginNewXlen, marginOldFront;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processPLCUpdateAfterIMDCT_fx", sizeof(struct {
+ Word16 oldLen, usedHistlen;
+ Counter i;
+ Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new;
+ Word16 frontLen, pastLen;
+ Word16 marginOldPast;
+ Word16 scale_fac_old_dual;
+ Word16 marginNewXlen, marginOldFront;
+ }));
+#endif
+
+
+
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("processPLCUpdateAfterIMDCT ");
+#endif
+
+
+ if (plcAd)
+ {
+ /* for short NB frames(2.5 ms) TDC-filtering requires more PCM samples than the plc_xcorr function */
+ usedHistlen = plcAd->max_len_pcm_plc;
+
+
+ logic16();
+ IF( (sub(bfi,1) == 0) && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0 && xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625))
+ { /* % reduced buffering update length during concealment method 2 as Xsav_fx is stored in the joint q_old_fx and pcmbufHist buffer */
+ usedHistlen = sub(usedHistlen, sub(LprotSzPtr[fs_idx], s_min(MAX_BW_BIN, xLen)));
+ ASSERT(xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625)); /*/ only enter here for 10 ms cases */
+
+ /* actually one can select to always update xLen(10 ms) less samples of x_old_tot, also in TDC-PLC bfi frames ,, and for PhECU.PLC */
+ }
+ oldLen = sub(usedHistlen, xLen);
+
+ /* update ltpf-free pcm history buffer for TD-PLC */
+
+ basop_memmove(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen],
+ &plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + xLen], oldLen * sizeof(Word16));
+
+ basop_memcpy(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], &x_fx[0], xLen * sizeof(Word16));
+
+#ifdef ENABLE_HR_MODE
+ frontLen = 0;
+ IF (sub(fs_idx, 5) < 0)
+#endif
+ {
+ frontLen = sub(LprotSzPtr[fs_idx], xLen); /*16-10 = 6ms of the prev_synth/xfp part */
+ }
+ pastLen = sub(oldLen, frontLen); /* ~11.8 ms*/
+
+ marginOldPast = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen]), pastLen);
+ marginOldFront = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + pastLen]), frontLen);
+
+ scale_fac_old = s_min(marginOldFront, marginOldPast);
+
+ frontLen = 0; move16();
+ logic16(); logic16();
+ IF(bfi == 1 && *prev_bfi == 0 && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0)
+ { /* prepare localized margin_xfp value for a next bad concealment Method 2 frame */
+ frontLen = *nbLostFramesInRow;
+ frontLen = add(hamm_len2Tab[fs_idx], shr(hamm_len2Tab[fs_idx], 2)); /* find margin in the 3.75 ms front part */
+ pastLen = sub(xLen, frontLen);
+ scale_fac_new = getScaleFactor16_0(&(x_fx[0]), pastLen);
+ marginNewXlen = getScaleFactor16_0(&(x_fx[0]) + pastLen, frontLen); /* for pHEcuprev_synth in 2nd+ bfi frame */
+
+ scale_fac_new = s_min(scale_fac_new, marginNewXlen);
+ }
+ ELSE
+ { /* prepare margin value for any coming good frame or any coming first bad frame */
+
+ marginNewXlen = getScaleFactor16_0(&(x_fx[0]),xLen); /* prevsynth in first bfi frame */
+ scale_fac_new = marginNewXlen; move16();
+ }
+
+ q_theo_new_old = s_max(plcAd->q_fx_old_exp - scale_fac_old, 0);
+ q_theo_new_new = s_max(q_fx_exp - scale_fac_new, 0);
+
+ q_new = s_max(q_theo_new_old, q_theo_new_new);
+
+ shift_old = plcAd->q_fx_old_exp - q_new;
+ shift_new = q_fx_exp - q_new;
+
+ IF(shift_old != 0)
+ {
+ Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen], oldLen, shift_old);
+ logic16();
+ test();
+ IF ((sub(bfi,1) == 0) && (sub(concealMethod, LC3_CON_TEC_TDPLC) == 0))
+ {
+ plcAd->harmonicBuf_Q -= shift_old;
+ plcAd->tdc_gain_c = L_shl_sat(plcAd->tdc_gain_c, shift_old);
+ }
+ move16(); /* count move to static RAM */
+
+ marginOldFront = s_min(16, sub(marginOldFront, shift_old));
+ }
+ IF(shift_new)
+ {
+ Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], xLen, shift_new); /* positive shift_new means upshift=less margin */
+ marginNewXlen = s_min(16, sub(marginNewXlen, shift_new));
+ }
+
+ plcAd->q_fx_old_exp = sub(q_fx_exp, shift_new);
+
+ plcAd->PhECU_margin_xfp = s_min(marginNewXlen, marginOldFront); move16(); /* for pHECU winEncalc xfp energy calculations */
+ if (frontLen != 0)
+ { /* prepare margin value for a first pHECU(16 ms) or a consecutive bad PhEcu frame (3.75ms) */
+ plcAd->PhECU_margin_xfp = marginNewXlen; move16();
+ }
+ if (sub(plcAd->PhECU_margin_xfp, 16) == 0)
+ {
+ plcAd->PhECU_margin_xfp = 1; move16(); /* "1" --> does not rescale the all-zero vector, inside PhECU */
+ }
+ }
+
+ /* Update PLC params */
+ IF(sub(bfi, 1) != 0)
+ {
+ /* % reset counters in GF */
+ *nbLostFramesInRow = 0; move16();
+ *ns_cum_alpha = 32767; move16();
+
+ if (plcAd)
+ {
+ basop_memmove(plcAd->old_old_scf_q, plcAd->old_scf_q, M * sizeof(Word16));
+ basop_memmove(plcAd->old_scf_q, scf_q, M * sizeof(Word16));
+
+ /* PLC fullband transient detector setting for non-bfi frames */
+ plcAd->PhECU_short_flag_prev = 0; move16(); /* fullband transient not active */
+ }
+ }
+
+ /* values may be {0,1,2} */
+ *prev_prev_bfi = *prev_bfi; move16();
+ *prev_bfi = bfi; move16();
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi, Word16 prev_bfi,
+ Word16 prev_prev_bfi, Word16 *stab_fac)
+{
+ IF (sub(bfi, 1) == 0)
+ {
+ IF (sub(prev_bfi, 1) != 0)
+ {
+ processPLCcomputeStabFac(old_scf_q, old_old_scf_q, prev_prev_bfi, stab_fac);
+ }
+ }
+ ELSE IF(sub(bfi, 2) == 0)
+ {
+ processPLCcomputeStabFac(scf_q, old_scf_q, prev_bfi, stab_fac);
+ }
+}
+
+static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac)
+{
+ Counter i;
+ Word32 tmp32;
+ Word16 d;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("calculateStabFac", sizeof(struct {
+ Counter i;
+ Word32 tmp32;
+ Word16 d;
+ }));
+#endif
+
+ /* calculate stability factor */
+ IF (sub(prev_bfi, 1) == 0)
+ {
+ *stab_fac = 26214; move16();
+ }
+ ELSE
+ {
+ tmp32 = 0; move32();
+ FOR (i = 0; i < M; i++)
+ {
+ d = sub(scf_q[i], old_scf_q[i]);
+ tmp32 = L_mac_sat(tmp32, d, d);
+ }
+ tmp32 = L_shl_sat(tmp32, 3);
+ IF (tmp32 > 0x7D000000 /*1.25*25*/)
+ {
+ *stab_fac = 0; move16();
+ }
+ ELSE IF (tmp32 < 0x19003E82 /*0.25*25*/)
+ {
+ *stab_fac = 0x7FFF; move16();
+ }
+ ELSE
+ {
+ tmp32 = L_shl_pos(L_sub(0x50000000 /*1.25/2*/, Mpy_32_16_lc3plus(tmp32, 0x51EC /*16/25*/)), 1);
+ *stab_fac = round_fx(tmp32); move16();
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi, Word16 *xfp_fx, Word16 xfp_exp_fx, Word16 margin_xfp,
+ Word16 fs_idx,
+ Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx,
+ Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx,
+
+ Word16 *oold_Ltot_exp_fx ,Word16 *old_Ltot_exp_fx )
+
+{
+ Word32 L_tot ;
+ Word16 dn_scale, exp_shift;
+ Word16 used_xfp_exp_fx;
+ Word16 exp_out ;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("PLCUpdateXFP_w_E_hist", sizeof(struct {
+ Word32 L_tot;
+ Word16 dn_scale, exp_shift;
+ Word16 used_xfp_exp_fx;
+ Word16 exp_out;
+ }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::UpdateXfp_w_E_hist_fx");
+#endif
+
+ IF (sub(bfi,1) != 0)
+ {
+
+ if (sub(prev_bfi,1) == 0)
+ {
+ /* only a single historic frame available in the next frame
+ , force artifical update of oold energy to be the same as old */
+ *old_xfp_w_E_exp_fx = LTOT_INIT_FLAG ; move16();
+ }
+
+ /* Time shift energy state and xfp exp */
+ IF (sub_sat(*old_xfp_w_E_exp_fx, LTOT_INIT_FLAG ) == 0)
+ {
+ *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32();
+ *oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16();
+ }
+ ELSE
+ {
+ *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */
+ *oold_xfp_w_E_exp_fx = *old_xfp_w_E_exp_fx; move16();
+ }
+
+ /* Time shift L_tot energy state and L_tot_exp */
+ IF (sub_sat(*old_Ltot_exp_fx, LTOT_INIT_FLAG ) == 0)
+ {
+ *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32();
+ *oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16();
+ }
+ ELSE
+ {
+ *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */
+ *oold_Ltot_exp_fx = *old_Ltot_exp_fx; move16();
+ }
+
+
+ dn_scale = e_tot_headroom[fs_idx]; /* allowed minimum dn_scale for a max upshifted signal */
+ used_xfp_exp_fx = xfp_exp_fx;
+
+ IF( margin_xfp > 0 ) /* xfp_fx was normalized on a larger area than 16ms part of pcmBuffer */
+ {
+ ASSERT(bfi !=1) ; /* if bfi was set the margin_xfp does not reflect the correct 16ms part of pcm_buf hist, prev_synth */
+ dn_scale = s_max(0, sub(e_tot_headroom[fs_idx], margin_xfp));
+
+ exp_shift = sub(e_tot_headroom[fs_idx], dn_scale);
+ used_xfp_exp_fx = sub(xfp_exp_fx, exp_shift); /* the virtual change of the xfp_buffer due to reduced downscaling in L_tot calc */
+ }
+
+ /* use semifixed dn_scale as adjusted by margin_xfp in 16 ms region */
+ exp_out = xfp_exp_fx; move16();
+ L_tot = winEnCalc(xfp_fx, dn_scale , PhECU_wins[fs_idx][0], rectLengthTab[fs_idx], hamm_len2Tab[fs_idx], &exp_out );
+
+ *L_old_xfp_w_E_fx = L_tot; move32();
+
+ *old_xfp_w_E_exp_fx = used_xfp_exp_fx ; move16();
+ /* this now needs to be in Q1 , used_fx_exp , (exp_out-1-2*e_tot_headroom[fs_idx])/2 */
+
+ *old_Ltot_exp_fx = exp_out; /* new proper _Ltot value from winEnCalc function */
+
+
+ /* use true Word32 exponent of L_tot */
+
+
+ /* restart oold and old from same state for init or prevBFI cases */
+ logic16();
+ IF (sub_sat(*oold_xfp_w_E_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 || /* old xfp_Exp */
+ sub_sat(*oold_Ltot_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 ) /* new L_tot_exp */
+ {
+ *L_oold_xfp_w_E_fx = L_tot; move32();
+ *oold_xfp_w_E_exp_fx = used_xfp_exp_fx; move16();
+ *oold_Ltot_exp_fx = *old_Ltot_exp_fx; /* use Ltot exp value */
+ }
+ }
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
+
diff --git a/lib_lc3plus/plc_update_fx.c b/lib_lc3plus/plc_update_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb05770d59aa1471da179018420e0de2f63d5770
--- /dev/null
+++ b/lib_lc3plus/plc_update_fx.c
@@ -0,0 +1,224 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length,
+ Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[],
+ Word16 *ns_cum_alpha
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+ )
+{
+ processPLCUpdateAfterIMDCT_fx(x_fx, q_fx_exp, concealMethod, frame_length, fs_idx, nbLostFramesInRow, prev_prev_bfi, prev_bfi, bfi,
+ scf_q, ns_cum_alpha, plcAd); /* NB *prev_bfi updated here */
+
+ IF ( plcAd != 0 )
+ {
+ /* reuse/inplace the most recent 16 ms of x_old_tot without additional rescaling, keep exponent aligned with tdc pitch buffer to save WMOPS */
+
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode == 0)
+#endif
+ {
+ ASSERT( (&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - LprotSzPtr[fs_idx] ]) == plcAd->PhECU_xfp_fx );
+ plcAd->PhECU_xfp_exp_fx = plcAd->q_fx_old_exp; move16(); /* exponent used by concealmethod 2 in prevBfi frames and also right after non bfi frames */
+ }
+ }
+}
+
+void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word16 s;
+ );
+
+ /* save spectrum and the corresponding exponent */
+ s = getScaleFactor32_lc3plus(q_d_fx, yLen);
+
+ *q_old_fx_exp = sub(*q_fx_exp, s);
+
+
+ FOR (i = 0; i < yLen; i++)
+ {
+ q_old_d_fx[i] = round_fx_sat(L_shl_sat(q_d_fx[i], s)); /* */
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen,
+ Word16 *stPhECU_oold_grp_shape_fx, Word16 *stPhECU_old_grp_shape_fx)
+
+#define L_GRP_DC 4
+
+{
+ Counter i,l;
+ Word16 *pX, tmp;
+ Word16 N_grp,l_grp;
+ Word16 man, expo;
+ Word32 L_acc;
+ Word32 L_tot;
+ Word32 L_grp_shape[MAX_LGW];
+ Word16 grp_shape[MAX_LGW]; /**/
+ Word16 fs_idx,local_prev_bfi;
+
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("process_plc_spec_2_shape_fx", sizeof(struct {
+ Counter i,l;
+ Word16 *pX;
+ Word16 N_grp,l_grp;
+ Word32 L_acc;
+ Word32 L_tot;
+ Word32 L_grp_shape[MAX_LGW];
+ Word16 fs_idx,local_prev_bfi;
+ }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("PhECU::GF::process_plc_spec_2_shape_fx");
+#endif
+
+ IF(sub(bfi, 1) != 0)
+ {
+ fs_idx = mult(yLen, (Word16)(32768.0 / (99.0))); /* truncation needed , i.e no rounding can be applied here */
+ N_grp = xavg_N_grp_fx[fs_idx]; move16();
+
+ local_prev_bfi = prev_bfi; move16();
+ if (sub(local_prev_bfi, 2)==0)
+ {
+ local_prev_bfi = 0; move16();
+ }
+
+ if( stPhECU_oold_grp_shape_fx[0] < 0 )
+ {
+ local_prev_bfi = 1 ; move16(); /* handle startup in the case 2nd frame is a BFI frame */
+ }
+
+ /* Copy old to oold grp shape */
+ FOR( i=0; i < MAX_LGW ; i++)
+ {
+ stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i]; move16();
+ }
+
+
+ /* Accumulate DC bin(s) to total */
+ pX = q_old_d_fx; /* ptr setup */
+ L_tot = L_deposit_h(0); /* acc on negative side */
+
+ FOR( i= 0; i < L_GRP_DC; i++)
+ {
+ tmp = shr_pos(*pX++ ,spec_shape_headroom[fs_idx]); /* scale down upscaled MDCT to create some headroom */
+ L_tot = L_msu0(L_tot, tmp, tmp);
+
+ }
+
+ /* Accumulate middle subbands and add to total */
+ FOR( i=0; i < sub(N_grp,1) ; i++)
+ {
+
+ L_acc = L_deposit_h(0); /* acc on negative side */
+ l_grp = sub(mdct_grp_bins_fx[i+1], mdct_grp_bins_fx[i]); move16();
+
+
+
+ FOR(l=0;l 0)
+ {
+ FOR(i=0; i < N_grp ; i++)
+ {
+ man = plc_phEcu_ratio_fx(L_grp_shape[i], L_tot, &expo); /* The mantissa is considered in Q15 output in Q14 */
+ grp_shape[i] = shr_sat(man, sub(expo,1)); /* gfrom Q14 to in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */
+ }
+ }
+ ELSE
+ {
+ FOR(i=0; i < N_grp ; i++)
+ {
+ grp_shape[i] = GRP_SHAPE_INIT; move16();
+
+ }
+ }
+
+ /* copy to output */
+ FOR(i=0; i < N_grp ; i++)
+ {
+ stPhECU_old_grp_shape_fx[i] = grp_shape[i]; move16();
+ }
+ FOR(i = N_grp; i < MAX_LGW ; i++)
+ {
+ stPhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT; move16();
+ }
+
+
+
+ /* handle oold states for the frame sequence BAD, GOOD, NEXT_BAD */
+ if(sub(local_prev_bfi, 1)==0)
+ {
+ FOR( i=0; i < MAX_LGW ; i++)
+ {
+ stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i] ; move16();
+ }
+ }
+
+ }
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+}
+
+
+
+
diff --git a/lib_lc3plus/plc_xcorr_fx.c b/lib_lc3plus/plc_xcorr_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..720015295531e8bc8c96acedc78d23471b8b01d9
--- /dev/null
+++ b/lib_lc3plus/plc_xcorr_fx.c
@@ -0,0 +1,250 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+#include "functions.h"
+
+#define MAX_ACCS 3 /* sum(x.*y), sum(x.*x), sum(y.*y), nb of always nonsaturated shorter sub_blocks*/
+#define MAX_BLOCKS 8
+#define MAX_ACC_LEN_BITS 7
+#define MIN_ACC_LEN_BITS 5
+#define MAX_ACC_LEN (1 << MAX_ACC_LEN_BITS)
+#define MIN_PITCH_8K 20 /* 8000* MIN_PITCH_12k8/12800 */
+
+static const Word16 pitch_min_2[] = {2 * MIN_PITCH_8K , 2 * MIN_PITCH_8K * 2, 2 * MIN_PITCH_8K * 3,
+ 2 * MIN_PITCH_8K * 4, 2 * MIN_PITCH_8K * 6, 2 * MIN_PITCH_8K * 12};
+
+/* req headroom in bits, for safe summing of block results w/o downshift */
+/* also the safe pre subblock acc downshift for various number of blocks */
+static const Word16 tab_req_headroom[MAX_BLOCKS + 1] = {0, 0, 1, 2, 2, 3, 3, 3, 3};
+/*(0, 1, 2, 3,4, 5,6,7,8)*/
+
+static Word16 plc_norm_corr_blocks_fx(Word16 tot_len, Word16 l2_base_len, Word16 n_blocks, Word16 inshift,
+ Word16 *currFrame, Word16 *predFrame);
+
+Word16 plc_norm_corr_blocks_fx( /* o: norm_corr range [-1 ... 1.0[ in Q15 */
+ Word16 tot_len, /* i: total correlation length in Q0 */
+ Word16 l2_base_len, /* i: size of subblocks in log2 */
+ Word16 n_blocks, /* i: number of accumulator sub_blocks */
+ Word16 inshift, /* i: required inshift of curr/pred Q0 */
+ Word16 *currFrame, /* i: ptr to most recent section */
+ Word16 *predFrame) /* i: ptr to historic section */
+{
+ Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin;
+ Word32 L_prod, L_inv, L_tmp0 = 0, L_tmp1 = 0, L_tmp2 = 0;
+ Word16 norm_corr, curr, pred;
+ Counter m, b;
+ Word32 L_ce[MAX_ACCS][MAX_BLOCKS];
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_norm_corr_blocks_fx", sizeof(struct {
+ Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin;
+ Word32 L_prod, L_inv, L_tmp0, L_tmp1, L_tmp2;
+ Word16 norm_corr, curr, pred;
+ Counter m, b;
+ Word32 L_ce[MAX_ACCS][MAX_BLOCKS];
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("plc_norm_corr_blocks_fx");
+#endif
+
+ /* Calculate normalized correlation with added shift and block interleaving possibility */
+ ASSERT(n_blocks <= MAX_BLOCKS && n_blocks > 0);
+ ASSERT(((float)tot_len / (float)n_blocks) <= (float)(1 << l2_base_len));
+ ASSERT(inshift > 0);
+ UNUSED(l2_base_len);
+
+ FOR (b = 0; b < n_blocks; b++)
+ { /* block loop with fixed pre_down shifting(inshift) of input signal */
+ curr = shr_pos(currFrame[b], inshift);
+ pred = shr_pos(predFrame[b], inshift);
+ L_tmp2 = L_deposit_l(0);
+ L_tmp0 = L_msu0(L_tmp2, curr, pred); /* acc L_tmp0 on negative side to avoid saturation for (-1*-1) */
+ L_tmp1 = L_msu0(L_tmp2, pred, pred); /* acc_energy on negative side */
+ L_tmp2 = L_msu0(L_tmp2, curr, curr); /* acc_energy on negative side */
+
+ FOR (m = (b + n_blocks); m < tot_len; m += n_blocks)
+ { /* interleaved accumulation over total length */
+ curr = shr_pos(currFrame[m], inshift);
+ pred = shr_pos(predFrame[m], inshift);
+ L_tmp0 = L_msu0(L_tmp0, curr, pred);
+ L_tmp1 = L_msu0(L_tmp1, pred, pred);
+ L_tmp2 = L_msu0(L_tmp2, curr, curr);
+ }
+
+ L_ce[0][b] = L_add(L_tmp0, 0); /* account for moves from register to stack memory */
+ L_ce[1][b] = L_add(L_tmp1, 0);
+ L_ce[2][b] = L_add(L_tmp2, 0);
+ }
+
+ /* aggregate interleaved subsections */
+ IF (sub(n_blocks, 1) >= 0)
+ { /* 100% safe non saturating L_ce with a safe acc_margin */
+ acc_margin = tab_req_headroom[n_blocks]; move16();
+
+ L_tmp0 = L_shr_pos(L_ce[0][0], acc_margin);
+ L_tmp1 = L_shr_pos(L_ce[1][0], acc_margin);
+ L_tmp2 = L_shr_pos(L_ce[2][0], acc_margin);
+
+ FOR (b = 1; b < n_blocks; b++)
+ {
+ L_tmp0 = L_add(L_tmp0, L_shr_pos(L_ce[0][b], acc_margin)); /* add negative values */
+ L_tmp1 = L_add(L_tmp1, L_shr_pos(L_ce[1][b], acc_margin)); /* add negative values */
+ L_tmp2 = L_add(L_tmp2, L_shr_pos(L_ce[2][b], acc_margin)); /* add negative values */
+ }
+
+ /* evaluate headroom margin in coarse representation */
+ scale0 = norm_l(L_tmp0);
+ scale1 = norm_l(L_tmp1);
+ scale2 = norm_l(L_tmp2);
+
+ scale_min = s_min(scale0, scale1);
+ scale_min = s_min(scale_min, scale2);
+
+ shift = sub(scale_min, acc_margin);
+ IF (shift >= 0)
+ { /* re-accumulate blocks with highest possible precision */
+ L_tmp0 = L_add(L_ce[0][0], 0); /* add negative values */
+ L_tmp1 = L_add(L_ce[1][0], 0); /* add negative values */
+ L_tmp2 = L_add(L_ce[2][0], 0); /* add negative values */
+
+ FOR (b = 1; b < n_blocks; b++)
+ {
+ L_tmp0 = L_add(L_tmp0, L_ce[0][b]); /* add negative values */
+ L_tmp1 = L_add(L_tmp1, L_ce[1][b]); /* add negative values */
+ L_tmp2 = L_add(L_tmp2, L_ce[2][b]); /* add negative values */
+ }
+ }
+ }
+
+ /* quota: norm_corr = corr/sqrt(en1*en2) = negate(L_tmp1)/sqrt(-L_tmp1*-L_tmp2) */
+ L_tmp1 = L_min(L_tmp1, -1); /* make sure there is negative energy */
+ L_tmp2 = L_min(L_tmp2, -1); /* make sure there is negative energy */
+
+ ASSERT(L_tmp1 < 0 && L_tmp2 < 0);
+
+ /* negate correlation, due to the used safe msu0 accumulation, with a saturation pre-check ctrl */
+ L_tmp0 = L_max(L_tmp0, (MIN_32 + 1));
+ L_tmp0 = L_negate(L_tmp0);
+
+ scale0 = norm_l(L_tmp0);
+ scale1 = norm_l(L_tmp1);
+ scale2 = norm_l(L_tmp2);
+
+ L_tmp1 = L_shl_pos(L_tmp1, scale1);
+ L_tmp2 = L_shl_pos(L_tmp2, scale2);
+ L_prod = Mpy_32_32_lc3plus(L_tmp1, L_tmp2); /* neg * neg -> positive */
+ shift = norm_l(L_prod);
+ L_prod = L_shl_pos(L_prod, shift);
+ prod_exp = sub(62, add(add(scale1, scale2), shift));
+ L_inv = Isqrt(L_prod, &prod_exp);
+
+ L_tmp0 = L_shl_pos(L_tmp0, scale0);
+ L_prod = Mpy_32_32_lc3plus(L_tmp0, L_inv);
+ prod_exp = add(sub(31, scale0), prod_exp);
+
+ norm_corr = 32767; move16(); /* as close to 1.0 as possible in Q15 */
+ if (L_tmp0 < 0)
+ {
+ norm_corr = -32768; move16(); /*-1.0*/
+ }
+
+ test();
+ IF (L_prod == 0 || sub(norm_l(L_prod), prod_exp) >= 0)
+ {
+ norm_corr = round_fx_sat(L_shl_sat(L_prod, prod_exp));
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return norm_corr;
+}
+
+Word16 plc_xcorr_lc_fx( /* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */
+ Word16 *pcmbuf_fx, /* i: NB should be an already dynamically upscaled pcm buffer with about
+ 0...1(2) bits margin */
+ Word16 max_len_pcm_plc, /* i: Q0 physical size of pcmbuf_fx */
+ Word16 pitch_int, /* i: Q0 in Fs, lag value to evaluate, corresponding to the current f0 in
+ pcm_buf_Fx */
+ Word16 fs_idx /*i: */)
+{
+ Word16 *range1Ptr;
+ Word16 *range2Ptr;
+ Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("plc_xcorr_lc_fx", sizeof(struct {
+ Word16 *range1Ptr;
+ Word16 *range2Ptr;
+ Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len;
+ }));
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("plc_xcorr_lc_fx");
+#endif
+
+ norm_xcorr_est_q = 0; move16();
+
+ IF (pitch_int > 0)
+ {
+ pcm_max_corr_len = sub(max_len_pcm_plc, pitch_int);
+
+ max_corr_len = rectLengthTab[fs_idx]; /* maximum 10 ms */
+ max_corr_len = s_min(max_corr_len, pcm_max_corr_len);
+
+ corr_len_fx = s_min(max_corr_len, pitch_int);
+ corr_len_fx = s_max(corr_len_fx, pitch_min_2[fs_idx]); /* at least 5 ms (=2*pitchmin*) corr length */
+
+ ASSERT(corr_len_fx >= (pitch_min_2[fs_idx])); /* at least 2 x pitch min(fs) */
+ ASSERT(corr_len_fx <= (MAX_ACC_LEN * MAX_BLOCKS));
+ ASSERT(corr_len_fx <= max_corr_len);
+ ASSERT( max_len_pcm_plc - corr_len_fx - pitch_int + 1 > 0 );
+
+ range1Ptr = &(pcmbuf_fx[max_len_pcm_plc]) - corr_len_fx; /* ptr setup, start of head section */
+ range2Ptr = range1Ptr - pitch_int; /* ptr setup, history = tail - lag distance */
+
+ /* assume 32 bit acc of up to 32 values -> sum(over 32, x_up>>2 * y_up>>2) */
+ inshift = 2; move16();
+ l2_base_len = MIN_ACC_LEN_BITS; move16();
+ n_blocks = shr(add(corr_len_fx, (1 << MIN_ACC_LEN_BITS) - 1), MIN_ACC_LEN_BITS);
+
+ IF (sub(n_blocks, MAX_BLOCKS) > 0)
+ { /* shift to 32 bit acc of up to 128 values -> sum(over 128, x_up>>3 * y_up>>3) */
+ inshift = 3; move16();
+ l2_base_len = MAX_ACC_LEN_BITS; move16();
+ n_blocks = shr(add(corr_len_fx, ((1 << MAX_ACC_LEN_BITS) - 1)), MAX_ACC_LEN_BITS);
+ }
+
+ ASSERT(n_blocks <= MAX_BLOCKS); /* MAX_BLOCKS*(32 or 128) is max possible total corr_length */
+ ASSERT(n_blocks > 0);
+
+ /* subblock accumulation of corr and energies, to achieve high low level precision */
+ norm_xcorr_est_q =
+ plc_norm_corr_blocks_fx(corr_len_fx, l2_base_len, n_blocks, inshift, range1Ptr, /* curr_frame */
+ range2Ptr); /* pred_frame = curr_frame-lag, i.e historic section */
+
+ norm_xcorr_est_q = s_max(0, norm_xcorr_est_q); /* do not allow negative output values */
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ return norm_xcorr_est_q;
+}
+
+
diff --git a/lib_lc3plus/pvq_dec_fx.c b/lib_lc3plus/pvq_dec_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..d77aae80964e4db1d7296152cdfe33165ed7880b
--- /dev/null
+++ b/lib_lc3plus/pvq_dec_fx.c
@@ -0,0 +1,153 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */
+ Word16 * y, /* o: decoded vector (non-scaled int) */
+ const Word16 k_val, /* i: number of allocated pulses */
+ const Word16 dim, /* i: Length of vector */
+ const Word16 LS_ind, /* i; lS index 1 bit */
+ const UWord32 UL_MPVQ_ind /* i; MPVQ index */
+)
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 BER_flag;
+ UWord32 h_mem[1 + KMAX_FX + 1];
+ PvqEntry_fx entry;
+ );
+
+ BER_flag = 0; move16();
+
+ /* get_size will likely be called before this function, as the range decoder needs the size to fetch the index
+ */
+ entry = get_size_mpvq_calc_offset_fx(dim, k_val, h_mem); /* TBD should be made into tables for N=16,10,6 */
+
+ entry.lead_sign_ind = LS_ind; move16();
+ entry.index = L_deposit_l(0); /* only in case dim == 1 */
+ IF (sub(dim, 1) != 0)
+ {
+ entry.index = UL_MPVQ_ind;
+
+ /* safety check in case of bit errors */
+ IF (L_sub(entry.index, entry.size) >= 0)
+ {
+ BER_flag = 1; move16();
+ entry.index = 0; move16(); /* return something deterministic/valid, and LOW complex */
+ }
+ }
+ mpvq_deindex_fx(&entry, h_mem, y); /* actual deindexing */
+
+ Dyn_Mem_Deluxe_Out();
+ return BER_flag;
+}
+
+
+
+#ifdef ENABLE_HR_MODE
+void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ)
+#else
+void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14)
+#endif
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+ FOR (i = 0; i < M; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ outQ[i] = L_shr(L_add(outQ[i], Mpy_32_16_lc3plus(inQ29[i], adjGainQ13)), 1);
+ move16();
+#else
+ outQ14[i] = add(outQ14[i], mult_r(adjGainQ13, inQ14[i])); move16();
+#endif
+ }
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+void pvq_dec_en1_normQ14_fx(/* Have to be used EXACTLY the same way in both both encoder and decoder */
+#ifdef ENABLE_HR_MODE
+ Word32 * xq, /* o: en1 normalized decoded vector (Q14) */
+#else
+ Word16 * xq, /* o: en1 normalized decoded vector (Q14) */
+#endif
+ const Word16 *y, /* i: decoded vector (non-scaled int) */
+ const Word16 k_val_max,
+ /* i: max possible K in Q0 kO or kA */ /* OPT: not BE , use dynamic max pulse
+ amplitude */
+ const Word16 dim /* i: Length of vector */
+)
+{
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 L_tmp;
+ Word16 shift_num, shift_tot;
+ Word32 isqrtQ31_local;
+ Word16 tmp, exp, exp_shift;
+ Word32 L_yy;
+ );
+#else
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 L_tmp;
+ Word16 shift_num, shift_tot;
+ Word16 isqrtQ16_local, tmp, exp, exp_shift;
+ Word32 L_yy;
+ );
+#endif
+
+/* energy normalization starts here */
+ L_yy = L_mult0(y[0], y[0]);
+ FOR (i = 1; i < dim; i++)
+ {
+ L_yy = L_mac0(L_yy, y[i], y[i]); /* stay in Q0 */ /* OPT: reuse some energies from PVQ linear search */
+ }
+ /* 16 bit */
+ IF (L_sub(L_yy, SQRT_EN_MAX_FX) < 0)
+ {
+ ASSERT(L_yy > 4); /* Q16 isqrt table lookup not valid below 5 */
+#ifdef ENABLE_HR_MODE
+ isqrtQ31_local = isqrt_Q31tab[L_yy]; move16(); /* 1 cycle */
+#else
+ isqrtQ16_local = isqrt_Q16tab[L_yy]; move16(); /* 1 cycle */
+#endif
+ }
+ ELSE
+ {
+ /* about 8-9 cycles */
+ exp = 15; move16(); /* set ISqrt16() exp_in to get delta exp out near 0 when Lyy is in Q0 */
+ tmp = ISqrt16(extract_l(L_yy),
+ &exp); /* exp out is now a delta shift with a later tmp Q15 multiplication in mind */
+#ifdef ENABLE_HR_MODE
+ exp_shift = add(exp, 16); /* up to Q16 */
+ isqrtQ31_local = L_shl(L_deposit_l(tmp), exp_shift); /* new mantissa in a fixed Q16 */
+#else
+ exp_shift = add(exp, 16 - 15); /* up to Q16 */
+ isqrtQ16_local = shl(tmp, exp_shift); /* new mantissa in a fixed Q16 */
+#endif
+ }
+
+ shift_num = norm_s(k_val_max); /* simply account for the preknown fixed max possible pulseamp in y */
+ shift_tot = sub(14 - 1, shift_num); /* upshift to get to Q14 */
+ FOR (i = 0; i < dim; i++) /* upshifted y[i] used */
+ {
+#ifdef ENABLE_HR_MODE
+ L_tmp = Mpy_32_16_lc3plus(isqrtQ31_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */
+ xq[i] = L_shl(L_tmp, shift_tot + 1); move32(); /* Q30 , */
+#else
+ L_tmp = L_mult(isqrtQ16_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */
+ xq[i] = round_fx(L_shl(L_tmp, shift_tot)); move16(); /* Q14 , */
+#endif
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/pvq_enc_fx.c b/lib_lc3plus/pvq_enc_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c164dda54e946aac8f0eda0f96667b6e7670de6
--- /dev/null
+++ b/lib_lc3plus/pvq_enc_fx.c
@@ -0,0 +1,369 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static void pvq_pyr_project(const Word16 dim_proj, /* end vector dimension+1 */
+ const Word16 *xabs, /* absolute vector values */
+ Word32 L_xsum, /* absolute vector sum over dim */
+ Word16 num, /* target number of pulses */
+ Word16 * y, /* projected output vector */
+ Word16 *pulse_tot_ptr, Word32 *L_xy_ptr, /* accumulated correlation Q(in+0+1) = Qin+1 */
+ Word32 *L_yy_ptr /* accumulated energy Q0 */
+)
+{
+
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word32 L_tmp, L_num;
+ Word16 den, shift_num, shift_den, shift_delta, proj_fac;
+ );
+
+ *pulse_tot_ptr = 0; move16();
+ *L_xy_ptr = L_deposit_l(0);
+ *L_yy_ptr = L_deposit_l(0);
+
+ shift_den = norm_l(L_xsum); /* x_sum input Qin */
+ den = extract_h(L_shl_pos(L_xsum, shift_den)); /* now in Qin+shift_den */
+
+ L_num = L_deposit_l(num);
+ shift_num = sub(norm_l(L_num), 1);
+ L_num = L_shl_pos(L_num, shift_num); /* now in Q0 +shift_num -1 */
+ proj_fac = div_l(L_num, den); /* L_num always has to be less than den<<16 , norm_l-1 makes that happen */
+
+ shift_delta = sub(shift_num, shift_den);
+ FOR (i = 0; i < dim_proj; i++)
+ {
+ L_tmp = L_mult(proj_fac, xabs[i]); /* Q shift_delta + PVQ_SEARCH_QIN */
+ y[i] = extract_h(L_shr(L_tmp, shift_delta)); move16(); /* to Q0 with floor , and potential sturation */
+ ;
+
+ *pulse_tot_ptr = add(*pulse_tot_ptr, y[i]); /* Q0 */
+ *L_yy_ptr = L_mac0(*L_yy_ptr, y[i], y[i]); /* Energy, Q0 */
+ *L_xy_ptr = L_mac(*L_xy_ptr, xabs[i], y[i]); /* Corr, Q0*Q12 +1 --> Q13 */
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+
+static __forceinline Word16 one_pulse_search(const Word16 dim_start, /* start vector dimension */
+ const Word16 dim_end, /* end vector dimension+1 */
+ const Word16 *x_abs, /* absolute vector values */
+ Word16 * y, /* output vector */
+ Word16 * pulse_tot_ptr,
+ Word32 * L_xy_ptr, /* accumulated correlation Q(12+0+1) = Q13 */
+ Word32 * L_yy_ptr, /* accumulated energy Q0 */
+ Word16 max_xabs) /* current max amplitude for target */
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word16 corr_tmp, corr_sq_tmp, en_max_den, cmax_num, en_tmp;
+ Word32 L_tmp_en_lc, L_tmp_corr;
+ Word16 corr_up_shift, imax;
+ );
+
+ /* maximize correlation precision, prior to every unit pulse addition in the vector */
+ corr_up_shift = norm_l(L_mac(*L_xy_ptr, 1, max_xabs)); /* pre analyze worst case L_xy update in the dim loop */
+ imax = -1; /* not needed for search, only added to avoid compiler warning */
+ {
+ en_max_den = 0; move16();
+ cmax_num = -1; move16(); /* req. to force a 1st update for n==dim_start */
+
+ FOR (i = dim_start; i < dim_end; i++)
+ {
+ L_tmp_corr = L_shl_pos(L_mac(*L_xy_ptr, 1, x_abs[i]), corr_up_shift); /* actual in-loop target value */
+
+ corr_tmp = round_fx_sat(L_tmp_corr);
+
+ corr_sq_tmp = mult(corr_tmp, corr_tmp); /* CorrSq_tmp for a 16bit low complexity cross multiplication */
+
+ L_tmp_en_lc = L_mac(*L_yy_ptr, 1, y[i]); /*Q0 x^2+ 2x , "+1" added once before loop , result , energy may
+ span up to ~14+1(Q1)+1(sign)=16 bits */
+ /* extract_l without shift can always be used for this section as energy is guaranteed to stay in the lower
+ * word*/
+
+ en_tmp = extract_l(L_tmp_en_lc); /* L_shl + round_fx could also be used also but then adds an uphift cost */
+
+ /* 16/32 bit comparison WC (4 +1+1 + (1+1+1) = 9 */
+ IF (L_msu(L_mult(corr_sq_tmp, en_max_den), cmax_num, en_tmp) > 0) /* use L_mult and then a L_msu */
+ {
+ cmax_num = corr_sq_tmp; move16();
+ en_max_den = en_tmp; move16();
+ imax = i; move16();
+ }
+ } /* dim */
+ }
+
+
+ /* finally add found unit pulse contribution to past L_xy, Lyy, for next pulse loop */
+ *L_xy_ptr = L_mac(*L_xy_ptr, x_abs[imax], 1); /* Qin+1 */
+ *L_yy_ptr = L_mac(*L_yy_ptr, 1, y[imax]);
+
+ y[imax] = add(y[imax], 1); move16(); /* Q0 added pulse */
+ (*pulse_tot_ptr) = add((*pulse_tot_ptr), 1); /* increment total pulse sum */
+ Dyn_Mem_Deluxe_Out();
+ return imax;
+}
+
+
+void pvq_enc_search_fx(
+ const Word16 *x, /* i: target vector to quantize Qin */
+ Word16 * y_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 , length dim */
+ Word16 * y, /* o: outl_near o, raw pulses (non-scaled short) Q0 , length dim */
+ Word16 * yA, /* o: A section raw pulses (non-scaled short) Q0 , length dimA */
+ Word16 * yB, /* o: B section raw pulses (non-scaled short) Q0 , length dim-dimA */
+ Word32 * L_corr, /* o: 4 un-normalized correlation sums for outl_far, outl_near, A, AB */
+ Word32 * L_search_en, /* o: 4 energy sums for outl_far, outl_near, A, AB */
+ Word16 * pulses_fin, /* i: number of allocated pulses to outl_far, outl_near , A, AB sections */
+ Word16 * pulses_proj, /* i: number of projection pulses for outl_far, outl_near, A, AB */
+
+ const Word16 dim, /* i: Length of outlier vector */
+ const Word16 dimA /* i: Length of vector A section */
+)
+{
+
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ Word16 pulse_tot_far, pulse_tot, pulse_totA, pulse_totB;
+ Word16 xabs[PVQ_MAX_VEC_SIZE];
+ Word16 max_xabs, max_xabsA, max_xabsB;
+ Word32 L_xsum, L_xsumA;
+ Word32 L_yy, L_xy;
+ Word16 imax;
+ Counter k;
+ Word16 dim_m1;
+ Word16 dimB;
+ const Word16 *xBptr;
+ Word16 pulses_far, pulses, pulsesA, pulsesB;
+ );
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("pvq_enc_search_fx");
+#endif
+
+ pulses_far = pulses_fin[0]; move16();
+ pulses = pulses_fin[1]; move16();
+ pulsesA = pulses_fin[2]; move16();
+ pulsesB = pulses_fin[3]; move16();
+
+ FOR (i = 0; i < N_SCF_SHAPES_ST2; i++)
+ {
+ L_corr[i] = L_deposit_l(0);
+ L_search_en[i] = L_deposit_l(0);
+ }
+
+ dimB = sub(dim, dimA);
+
+ L_xsum = L_deposit_h(0);
+
+ max_xabs = -1; move16();
+ max_xabsA = -1; move16();
+ max_xabsB = -1; move16();
+ FOR (i = 0; i < dimA; i++)
+ {
+ xabs[i] = abs_s(x[i]); move16(); /* Qx */
+ max_xabsA = s_max(max_xabsA, xabs[i]); /* for efficient search correlation scaling */
+ L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */
+ }
+
+ basop_memset(y_far, 0, dim * sizeof(Word16));
+ basop_memset(y, 0, dimA * sizeof(Word16));
+ basop_memset(yA, 0, dimA * sizeof(Word16));
+
+ L_xsumA = L_add(L_xsum, 0); /* save for section A projection */
+
+ FOR (i = dimA; i < dim; i++)
+ {
+ xabs[i] = abs_s(x[i]); move16(); /* Qx */
+ max_xabsB = s_max(max_xabsB, xabs[i]); /* for efficient search correlation scaling */
+ L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */
+ }
+
+ basop_memset(&y[dimA], 0, (dim - dimA) * sizeof(Word16));
+
+ basop_memset(yB, 0, dimB * sizeof(Word16));
+
+ max_xabs = s_max(max_xabsA, max_xabsB); /* global max abs value */
+
+ test();
+ IF (L_xsum == 0)
+ { /* no shape in any section, projection in outl_far, outl_near, A, AB not possible, any search meaningless */
+
+ dim_m1 = sub(dim, 1);
+ y_far[0] = shr_pos(pulses_far, 1); move16();
+ y_far[dim_m1] = add(y_far[dim_m1], sub(pulses_far, y_far[0])); move16();
+
+ dim_m1 = sub(dim, 1);
+ y[0] = shr_pos(pulses, 1); move16();
+ y[dim_m1] = add(y[dim_m1], sub(pulses, y[0])); move16();
+
+ dim_m1 = sub(dimA, 1);
+ yA[0] = shr_pos(pulsesA, 1); move16();
+ yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16();
+
+ dim_m1 = sub(dimB, 1);
+ yB[0] = shr_pos(pulsesB, 1); move16();
+ yB[dim_m1] = add(yB[dim_m1], sub(pulsesB, yB[0])); move16();
+ }
+ ELSE
+ {
+ ASSERT(pulses_proj[0] > 0);
+ ASSERT(L_xsum > 0);
+
+ pvq_pyr_project(dim, xabs, L_xsum, pulses_proj[0], y_far, &pulse_tot_far, &L_xy,
+ &L_yy); /* outlier submode projection */
+
+ ASSERT(pulses_far <= 127);
+ FOR (k = pulse_tot_far; k < pulses_far; k++)
+ {
+ L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */
+ imax = one_pulse_search(0, dim, xabs, y_far, &pulse_tot_far, &L_xy, &L_yy, max_xabs);
+ }
+ ASSERT(pulse_tot_far == pulses_far);
+ /* outlier far submode result vector in y_far[0...15] */
+ L_corr[0] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */
+
+ basop_memmove(y, y_far, dim * sizeof(Word16)); /*y_far->y */
+
+ pulse_tot = pulse_tot_far; move16();
+
+ ASSERT(pulses <= 127);
+ FOR (k = pulse_tot; k < pulses; k++)
+ {
+ L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */
+ imax = one_pulse_search(0, dim, xabs, y, &pulse_tot, &L_xy, &L_yy, max_xabs);
+ }
+
+ /* outlier near submode result vector in y[0...15] */
+ L_corr[1] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */
+
+ ASSERT(pulse_tot == pulses);
+
+ IF (L_xsumA == 0)
+ {
+ /* no shape in A section, projection in A not possible, search meaningless */
+ dim_m1 = sub(dimA, 1);
+ yA[0] = shr_pos(pulsesA, 1); move16();
+ yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16();
+ }
+ ELSE
+ {
+ IF (pulses_proj[2] != 0) /* fixed setup if bitrate is fixed */
+ {
+ ASSERT(pulses_proj[2] > 0);
+ ASSERT(L_xsumA > 0);
+ pvq_pyr_project(dimA, xabs, L_xsumA, pulses_proj[2], yA, &pulse_totA, &L_xy,
+ &L_yy); /* section A , in submode 1 projection */
+ }
+ ELSE
+ {
+ /* default, otherwise recalculate A from outlier result (to remove any section B pulses influence)
+ */
+ pulse_totA = 0; move16();
+ L_xy = L_deposit_l(0);
+ L_yy = L_deposit_l(0);
+
+ basop_memmove(yA, y, dimA * sizeof(Word16));
+ FOR (i = 0; i < dimA; i++)
+ {
+ pulse_totA = add(pulse_totA, yA[i]); /* Q0 */
+ L_xy = L_mac(L_xy, xabs[i], yA[i]); /* Corr, Q0*Q12 +1 --> Q13 */
+ L_yy = L_mac(L_yy, yA[i], yA[i]); /* Energy, Q(0+0)+1)= Q1 */
+ }
+ L_yy = L_shr_pos(L_yy, 1); /* En to Q0 */
+ }
+
+ /* search remaining pulses in regular section A */
+ FOR (k = pulse_totA; k < pulsesA; k++)
+ {
+ L_yy = L_add(L_yy, 1); /* 1 added in Q0 */
+ imax = one_pulse_search(0, dimA, xabs, yA, &pulse_totA, &L_xy, &L_yy, max_xabsA);
+ }
+ ASSERT(pulse_totA == pulsesA);
+ } /* L_xsumA!=0 */
+
+ /* reg Set A result vector now in yA[0...9] */
+ L_corr[2] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */
+
+ /* search remaining pulses in regular section B, even if energy in B is zero */
+ ASSERT(pulses_proj[3] == 0);
+ pulse_totB = 0; move16();
+
+ IF (sub(pulsesB, 1) == 0)
+ { /* LC search, sufficient to find a single max, as pulses can not be stacked, when nb-pulses==1 */
+ imax = 0; move16(); /* safety */
+ FOR (i = dimA; i < dim; i++)
+ {
+ if (xabs[i] == max_xabsB)
+ {
+ imax = sub(i, dimA);
+ }
+ }
+ pulse_totB = 1; move16();
+ yB[imax] = 1; move16(); /* reg set B result vector in yB[0...5] */
+ L_xy = L_mac(L_xy, xabs[add(imax, dimA)], 1); /* calc total corr for A+B sections */
+ L_yy = L_add(L_yy, 1);
+ }
+ ELSE
+ { /* more than one target pulse in section B */
+ /* keep A pulses influence, search section B pulses influence */
+ FOR (k = pulse_totB; k < pulsesB; k++)
+ {
+ L_yy = L_add(L_yy, 1); /* 1 added in Q0*/
+ imax = one_pulse_search(dimA, dim, xabs, &(yB[-dimA]), &pulse_totB, &L_xy, &L_yy, max_xabsB);
+ }
+ }
+
+ L_corr[3] = L_shr_pos(L_xy, 1); move32(); /* to Qin*Q0 , corr of combined A and B */
+
+ ASSERT(pulse_totB == pulsesB);
+ /* reg set B result vector now in yB[0...5] */
+ } /* L_xsum != 0 */
+
+/* apply sign of (x) to first orthant result */
+ FOR (i = 0; i < dim; i++)
+ {
+ if (x[i] < 0)
+ {
+ y_far[i] = negate(y_far[i]); /* apply sign for outlier far */
+ }
+ }
+
+ FOR (i = 0; i < dim; i++)
+ {
+ if (x[i] < 0)
+ {
+ y[i] = negate(y[i]); /* apply sign for outliers near */
+ }
+ }
+
+ xBptr = &(x[dimA]); move32(); /* ptr init to B target section */
+ FOR (i = 0; i < dimA; i++)
+ {
+ if (x[i] < 0)
+ {
+ yA[i] = negate(yA[i]); /* apply sign in N_SETA */
+ }
+ }
+
+ FOR (i = 0; i < (dimB); i++)
+ {
+ if (xBptr[i] < 0)
+ {
+ yB[i] = negate(yB[i]); /* apply sign in N_SETB */
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
diff --git a/lib_lc3plus/pvq_index_fx.c b/lib_lc3plus/pvq_index_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..c7d63c8400867a49f0159aa6061a9d17bc41bf8e
--- /dev/null
+++ b/lib_lc3plus/pvq_index_fx.c
@@ -0,0 +1,513 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+#define SIGNBIT_FX 0x80000000u
+#define SIGNBIT_SHRT_FX 0x8000
+
+static void initOffsets_fx(Word16 dim_in, UWord32 *h_mem,
+ Word16 k_val_in) /* may be removed with tables for N=16,10,6 */
+{
+ UWord32 k_val_prev, k_val_curr;
+ UWord32 k_val, UL_k_val_in;
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("initOffsets_fx", sizeof(struct {
+ UWord32 k_val_prev, k_val_curr;
+ UWord32 k_val, UL_k_val_in;
+ }));
+#endif
+
+ h_mem[0] = UL_deposit_l(0);
+ h_mem[1] = UL_deposit_l(1);
+
+ UL_k_val_in = UL_deposit_l(k_val_in);
+ IF (sub(dim_in, 2) == 0)
+ {
+ FOR (k_val = 2; k_val <= UL_k_val_in; k_val++)
+ {
+ h_mem[k_val] = UL_subNsD(UL_lshl(k_val, 1), 1U); move32();
+ }
+ h_mem[k_val] = UL_k_val_in; move32();
+ }
+ ELSE
+ {
+ k_val_prev = UL_deposit_l(1U);
+ FOR (k_val_curr = 2; k_val_curr <= UL_k_val_in; k_val_curr++)
+ {
+ h_mem[k_val_curr] = UL_addNsD(1U, UL_Mpy_32_32(k_val_curr, UL_lshl(k_val_prev, 1))); move32();
+ k_val_prev = UL_addNsD(k_val_curr, 0U);
+ }
+ h_mem[k_val_curr] = UL_Mpy_32_32(k_val_curr, k_val_prev); move32();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static void a_fwd_fx(UWord32 *a_in, /* i/o: offsets */
+ Word16 n_items /* i : items, k's */
+)
+{
+ UWord32 a_1, a_in0;
+ Counter i;
+ UWord32 *a_in_prev_ptr;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("a_fwd_fx", sizeof(struct {
+ UWord32 a_1, a_in0;
+ Counter i;
+ UWord32 *a_in_prev_ptr;
+ }));
+#endif
+
+ a_in0 = UL_deposit_l(1);
+
+ a_in_prev_ptr = &(a_in[-1]);
+ FOR (i = 1; i <= n_items; i++)
+ {
+ a_1 = UL_addNsD(a_in0, UL_addNsD(a_in_prev_ptr[i], a_in[i]));
+ a_in_prev_ptr[i] = a_in0; move32();
+ a_in0 = UL_addNsD(a_1, 0U);
+ }
+ a_in_prev_ptr[i] = a_in0; move32();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static void a_bwd_fx(UWord32 *a_in, /* i/o: offsets */
+ Word16 n_items /* i: n_items */
+)
+{
+ UWord32 a_1, a_in0;
+ Counter i;
+ UWord32 *a_in_prev_ptr;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("a_bwd_fx", sizeof(struct {
+ UWord32 a_1, a_in0;
+ Counter i;
+ UWord32 *a_in_prev_ptr;
+ }));
+#endif
+
+ a_in0 = UL_deposit_l(0);
+ a_in_prev_ptr = &(a_in[-1]);
+
+ FOR (i = 1; i <= n_items; i++)
+ {
+ a_1 = UL_subNsD(UL_subNsD(a_in[i], a_in0), a_in_prev_ptr[i]);
+ a_in_prev_ptr[i] = a_in0; move32();
+ a_in0 = UL_addNsD(a_1, 0U);
+ }
+ a_in_prev_ptr[i] = a_in0; move32();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static void a_u_fwd_fx(UWord32 *a_u_in, Word16 k_val_in, Word16 mem_size_m1)
+{
+ UWord32 u_kp1_prev, u_kp1;
+ UWord32 u_k_prev;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("a_u_fwd_fx", sizeof(struct {
+ UWord32 u_kp1_prev, u_kp1;
+ UWord32 u_k_prev;
+ }));
+#endif
+
+ u_kp1_prev = a_u_in[mem_size_m1]; move32();
+ u_k_prev = UL_lshr(a_u_in[k_val_in], 1);
+
+ a_fwd_fx(&a_u_in[1], k_val_in);
+
+ u_kp1 = UL_lshr(a_u_in[k_val_in], 1);
+ a_u_in[mem_size_m1] = UL_addNsD(1U, UL_addNsD(u_kp1_prev, UL_addNsD(u_k_prev, u_kp1)));
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static Word16 get_lead_sign_fx(UWord32 *ind)
+{
+ Word16 leading_sign;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("get_lead_sign_fx", sizeof(struct { Word16 leading_sign; }));
+#endif
+
+ leading_sign = 1; move16();
+ if (UL_and(*ind, 1) != 0)
+ {
+ leading_sign = -1; move16();
+ }
+ (*ind) = UL_lshr(*ind, 1);
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+ return leading_sign;
+}
+
+/*-------------------------------------------------------------------*
+ * mind2vec_one_fx()
+ *-------------------------------------------------------------------*/
+static void mind2vec_one_fx(Word16 k_val_in, /* i: nb unit pulses , [ 0...K_MAX ] */
+ Word16 leading_sign, /* i: leading sign -1, 0, 1*/
+ UWord32 ind, /* i: index */ /* parameter could be omitted */
+ Word16 *vec_out /* o: pulse train */
+)
+{
+ *vec_out = (Word16)ind; /* dummy assignment to handle the common ind parameter warning */
+
+ if (leading_sign < 0)
+ {
+ k_val_in = negate(k_val_in);
+ }
+ *vec_out = k_val_in; move16();
+}
+
+static Word16 setval_update_sign_fx(Word16 k_delta, Word16 k_max_local, Word16 *leading_sign, UWord32 *ind_in,
+ Word16 *vec_out)
+{
+ IF (k_delta != 0)
+ {
+ mind2vec_one_fx(k_delta, *leading_sign, *ind_in, vec_out);
+ *leading_sign = get_lead_sign_fx(ind_in);
+ k_max_local = sub(k_max_local, k_delta);
+ }
+ return k_max_local;
+}
+
+/*-------------------------------------------------------------------*
+ * mind2vec_fx()
+ *-------------------------------------------------------------------*/
+static void mind2vec_fx(Word16 dim_in, /* i: dimension */
+ Word16 k_max_local, /* i: nb unit pulses */
+ Word16 leading_sign, /* i: leading sign */
+ UWord32 ind, /* i: index */
+ Word16 * vec_out, /* o: pulse train */
+ UWord32 *h_in /* i: offset vector A=1+2U */
+)
+{
+ Counter pos;
+ Word16 k_acc, k_delta;
+ UWord32 UL_tmp_offset, UL_diff;
+ UWord16 sgn;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("mind2vec_fx", sizeof(struct {
+ Counter pos;
+ Word16 k_acc, k_delta;
+ UWord32 UL_tmp_offset, UL_diff;
+ UWord16 sgn;
+ }));
+#endif
+
+ k_acc = k_max_local; move16();
+ FOR (pos = 0; pos < dim_in; pos++)
+ {
+
+ IF (ind != 0)
+ {
+
+ k_acc = k_max_local; move16();
+
+ UL_tmp_offset = UL_addNsD(h_in[k_acc], 0U);
+
+ UL_diff = UL_subNs(ind, UL_tmp_offset, &sgn);
+
+ WHILE (sgn)
+ {
+ UL_diff = UL_subNs(ind, h_in[--k_acc], &sgn);
+ }
+
+ ind = UL_addNsD(UL_diff, 0U);
+
+ k_delta = sub(k_max_local, k_acc);
+ }
+ ELSE
+ {
+ mind2vec_one_fx(k_max_local, leading_sign, ind, &vec_out[pos]);
+ BREAK;
+ }
+
+ k_max_local = setval_update_sign_fx(k_delta, k_max_local, &leading_sign, &ind, &vec_out[pos]);
+
+ a_bwd_fx(h_in, add(k_max_local, 1));
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+PvqEntry_fx get_size_mpvq_calc_offset_fx( /* o : size, dim, k_val */
+ Word16 dim_in, /* i : dimension */
+ Word16 k_val_in, /* i : nb unit pulses */
+ UWord32 *h_mem /* o : offsets */
+)
+{
+ Counter i;
+ PvqEntry_fx entry;
+ Word16 kp1;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("get_size_mpvq_calc_offset_fx", sizeof(struct {
+ Counter i;
+ PvqEntry_fx entry;
+ Word16 kp1;
+ }));
+#endif
+
+ entry.dim = dim_in; move16();
+ entry.k_val = k_val_in; move16();
+
+ entry.index = L_deposit_l(0);
+ entry.lead_sign_ind = 0; move16();
+
+ ASSERT(dim_in <= M);
+ ASSERT(tabledKMAX[dim_in] != 0);
+
+ /* tabled values for worst case K */ /* made into table lookup for N=16, 10, 6 */
+ kp1 = add(k_val_in, 1);
+ FOR (i = 0; i <= kp1; i++) /* A+U copying */
+ {
+ h_mem[i] =
+ UL_addNsD(MPVQ_offs_ptr[dim_in][i], 0U); /* a vector copying is needed as MPVQ recursion is in place */
+ }
+ /* special handling of last U offset in k+1 column */
+ if (sub(k_val_in, tabledKMAX[dim_in]) != 0)
+ {
+ h_mem[kp1] = UL_lshr(h_mem[kp1], 1); /* (A+1)/2 , convert from A(K+1) to U(K+1) domain */
+ }
+ entry.size =
+ UL_addNsD(1U, UL_addNsD(h_mem[kp1], UL_lshr(h_mem[k_val_in], 1))); /* MPVQ size calc. 1 + H(K+1) + (A(K)>>1) */
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+ return entry;
+}
+
+/*-------------------------------------------------------------------*
+ * mpvq_deindex_fx()
+ *-------------------------------------------------------------------*/
+void mpvq_deindex_fx( /* o : void */
+ const PvqEntry_fx *entry, /* i : sign_ind, index, dim, k_val */
+ UWord32 * h_mem, /* i : A/U offsets */
+ Word16 * vec_out /* o : pulse train */
+)
+{
+ Word16 leading_sign;
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("mpvq_deindex_fx", sizeof(struct { Word16 leading_sign; }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("mpvq_deindex_fx");
+#endif
+
+ basop_memset(vec_out, 0, (entry->dim) * sizeof(Word16));
+
+ leading_sign = 1; move16();
+ if (entry->lead_sign_ind != 0)
+ {
+ leading_sign = -1; move16();
+ }
+
+ IF (entry->k_val != 0)
+ {
+ mind2vec_fx(entry->dim, entry->k_val, leading_sign, entry->index, vec_out, h_mem);
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+}
+
+/*-------------------------------------------------------------------*
+ * vec2mind_two_fx()
+ *-------------------------------------------------------------------*/
+static void vec2mind_two_fx(const Word16 *vec_in, /* i : PVQ pulse train */
+ Word16 * k_val_out_ptr, /* o : number of unit pulses */
+ UWord32 * next_sign_ind, /* i/o: next sign ind */
+ UWord32 * ind /* o: MPVQ index */
+)
+{
+ UWord32 lead_sign_ind_add;
+ Word16 abs0, abs1, abs01, sptr;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("vec2mind_two_fx", sizeof(struct {
+ UWord32 lead_sign_ind_add;
+ Word16 abs0, abs1, abs01, sptr;
+ }));
+#endif
+
+ abs0 = abs_s(vec_in[0]);
+ abs1 = abs_s(vec_in[1]);
+ abs01 = add(abs0, abs1);
+ *k_val_out_ptr = abs01; move16();
+ *ind = UL_deposit_l(0);
+
+ *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX);
+
+ IF (abs01 != 0)
+ {
+ sptr = 0; move16();
+ *next_sign_ind = UL_deposit_l(sptr);
+
+ test();
+ IF (abs0 != 0 && abs1 != 0)
+ {
+ lead_sign_ind_add = UL_deposit_l(1);
+ if (vec_in[1] < 0)
+ {
+ lead_sign_ind_add = UL_deposit_l(2);
+ }
+ *ind = UL_addNsD(UL_deposit_l((UWord16)lshl(sub(abs1, 1), 1)), lead_sign_ind_add);
+ }
+ ELSE
+ {
+ IF (abs0 == 0)
+ {
+ *ind = UL_deposit_l((UWord16)sub(lshl(abs1, 1), 1));
+ sptr = 1; move16();
+ }
+ }
+
+ if (vec_in[sptr] < 0)
+ {
+ *next_sign_ind = UL_deposit_l(1);
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+static void enc_push_sign(Word16 val, UWord32 *next_sign_ind, UWord32 *index)
+{
+ test();
+ IF ((UL_and(*next_sign_ind, SIGNBIT_FX) == 0) && (val != 0))
+ {
+ *index = UL_addNsD(UL_lshl(*index, 1), *next_sign_ind);
+ }
+ if (val < 0)
+ {
+ *next_sign_ind = UL_deposit_l(1);
+ }
+ if (val > 0)
+ {
+ *next_sign_ind = UL_deposit_l(0);
+ }
+}
+
+static void vec2mind_fx(Word16 dim_in, /* i : dim */
+ Word16 k_val_in, /* i : number of unit pulses */
+ const Word16 *vec_in, /* i : PVQ pulse train */
+ UWord32 * next_sign_ind, /* o : pushed leading sign */
+ UWord32 * index, /* o : MPVQ index */
+ UWord32 * N_MPVQ_ptr, /* o : size(N_MPVQ(dim,K_val_in))*/
+ UWord32 * h_mem) /* o : offsets */
+{
+ Counter pos;
+ Word16 mem_size_m1, k_val_acc, tmp_val;
+ UWord32 tmp_h;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("vec2mind_fx", sizeof(struct {
+ Counter pos;
+ Word16 mem_size_m1, k_val_acc, tmp_val;
+ UWord32 tmp_h;
+ }));
+#endif
+
+ mem_size_m1 = add(k_val_in, 1);
+ *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX);
+
+ pos = sub(dim_in, 2);
+ vec2mind_two_fx(&vec_in[pos], &k_val_acc, next_sign_ind, index);
+ initOffsets_fx(3, h_mem, k_val_in);
+
+ tmp_h = h_mem[k_val_acc]; move32();
+ FOR (pos--; pos >= 0; pos--)
+ {
+ tmp_val = vec_in[pos]; move16();
+ enc_push_sign(tmp_val, next_sign_ind, index);
+
+ *index = UL_addNsD(*index, tmp_h);
+
+ k_val_acc = add(k_val_acc, abs_s(tmp_val));
+
+ IF (pos != 0)
+ {
+ a_u_fwd_fx(h_mem, k_val_in, mem_size_m1);
+ }
+ tmp_h = UL_addNsD(h_mem[k_val_acc], 0U);
+ }
+ *N_MPVQ_ptr = UL_addNsD(1U, UL_addNsD(UL_lshr(tmp_h, 1), h_mem[mem_size_m1])); move32();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+PvqEntry_fx mpvq_index_fx( /* o : leading_sign_index, index, size, k_val */
+ const Word16 *vec_in, /* i : signed pulse train */
+ Word16 dim_in, /* i : dimension */
+ Word16 k_val_local /* i : nb unit pulses */
+)
+{
+ PvqEntry_fx result;
+ UWord32 h_mem[1 + KMAX_FX + 1];
+ UWord32 lead_sign_ind;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("mpvq_index_fx", sizeof(struct {
+ PvqEntry_fx result;
+ UWord32 h_mem[1 + KMAX_FX + 1];
+ UWord32 lead_sign_ind;
+ }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("mpvq_index_fx");
+#endif
+
+ ASSERT(k_val_local <= KMAX_FX);
+
+ result.k_val = k_val_local; move16();
+ result.dim = dim_in; move16();
+
+ vec2mind_fx(dim_in, k_val_local, vec_in, &lead_sign_ind, &result.index, &result.size, h_mem);
+
+ result.lead_sign_ind = u_extract_l(lead_sign_ind);
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ return result;
+}
+
diff --git a/lib_lc3plus/quantize_spec_fx.c b/lib_lc3plus/quantize_spec_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..4667cf14639a9694b3c0e96fba394a7a97f804ff
--- /dev/null
+++ b/lib_lc3plus/quantize_spec_fx.c
@@ -0,0 +1,1167 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+# ifdef ENABLE_HR_MODE
+void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target,
+ Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout,
+ Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode)
+{
+
+ Word32 a1, b1, a1_i, b1_i;
+ Word16 t, lev1;
+ Word16 lastnz, lastnz2;
+ Word16 rateFlag;
+ Word32 nbits32, nbits232, target32;
+ Word16 nt_half;
+ Word32 c, ab_max, msb, a1_msb, b1_msb;
+ Word16 levmax;
+ Word16 s;
+ Word16 totBits, nbits_lsb;
+ Counter k, lev;
+ Word16 maxlevs;
+# ifndef FUNCTION_quantizeSpec_func1
+ Word16 tmp16;
+ Word32 offs32;
+ Counter i;
+# else
+ Word32 ARM_params[3];
+# endif
+
+# ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct {
+ Word32 a1, b1, a1_i, b1_i, ab_max, c;
+ Word16 t, lev1;
+ Word16 lastnz, lastnz2;
+ Word16 rateFlag;
+ Word32 nbits32, nbits232;
+ Word16 nt_half;
+ Word16 msb, a1_msb, b1_msb, levmax;
+ Counter k, lev, i;
+ Word16 s;
+ Word16 tmp16;
+ Word32 offs32, target32;
+ Word16 totBits, nbits_lsb;
+ Word16 maxlevs;
+ }));
+# endif
+
+ assert(target >= 0);
+
+ /* Quantization */
+ gain = invFixp(gain, &gain_e);
+
+ maxlevs = 21;
+ IF (hrmode)
+ {
+ s = sub(add(x_e, gain_e), 23);
+ s = s_min(s, 31);
+# ifdef FUNCTION_quantizeSpec_func1
+ ARM_params[0] = gain;
+ ARM_params[1] = s;
+
+ quantizeSpec_func1_hr_ip(xq, x, nt, ARM_params);
+# else
+ IF(s > 4)
+ {
+ s = sub(s, 4); /* Use extra bits of precision for fine calculation */
+ FOR(i = 0; i < nt; i++)
+ {
+ offs32 = Mpy_32_32_lc3plus(L_shl_pos(x[i], s), gain); /* multiply */
+ xq[i] = L_shr_r_pos(offs32, 4); /* Convert to Q0 with rounding */
+ /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */
+
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR(i = 0; i < nt; i++)
+ {
+ offs32 = Mpy_32_32_lc3plus(x[i], gain); /* multiply */
+ offs32 = L_shl(offs32, s); /* convert to 23Q8 */
+ xq[i] = L_shr_r_pos(offs32, 8); /* Convert to Q0 with rounding */
+ /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */
+
+ move32();
+ }
+ }
+# endif /* FUNCTION_quantizeSpec_func1 */
+ }
+ ELSE
+ {
+ s = sub(add(x_e, gain_e), 15);
+ s = s_max(s_min(s, 15), -15);
+# ifdef FUNCTION_quantizeSpec_func1
+ ARM_params[0] = gain;
+ ARM_params[1] = s;
+ ARM_params[2] = -4096;
+ quantizeSpec_func1_ip(xq, x, nt, ARM_params);
+# else
+ FOR (i = 0; i < nt; i++)
+ {
+ offs32 = Mpy_32_32_lc3plus(L_abs(x[i]), gain); /* multiply */
+ offs32 = L_shl(offs32, s); /* convert to 15Q16 */
+ tmp16 = mac_r(offs32, -4096, 1); /* add offset and truncate */
+
+ if (x[i] < 0)
+ tmp16 = negate(tmp16); /* restore sign */
+
+ /* Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375
+ quant_offset is -0.125 in Q15 and round adds 0.5 in Q16. Hence
+ mac_r results in abs(x[i])/gain - 0.125 + 0.5 = abs(x[i])/gain + 0.375.
+ Due to the abs and negate combination this achieves the same result
+ as spec.
+ */
+
+ xq[i] = tmp16;
+ move16();
+ }
+# endif /* FUNCTION_quantizeSpec_func1 */
+ }
+ /* Rate flag */
+ rateFlag = 0;
+ move16();
+ if (fs_idx != 5)
+ {
+ if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0)
+ {
+ rateFlag = 2 << NBITS_CONTEXT;
+ move16();
+ }
+ }
+
+ /* Init */
+ nt_half = shr_pos(nt, 1);
+ c = 0;
+ move16();
+ t = 0;
+ move16();
+ a1_i = 0;
+ move16();
+ b1_i = 1;
+ move16();
+ target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q);
+ nbits32 = L_negate(target32);
+ nbits232 = 0;
+ move32();
+ nbits_lsb = 0;
+ move16();
+
+ if (fs_idx != 5)
+ {
+ IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0)
+ {
+ mode = 1;
+ move16();
+ }
+ }
+
+ /* Find last non-zero tuple */
+ lastnz = find_last_nz_pair(xq, nt);
+ IF (mode >= 0)
+ {
+ lastnz2 = 2;
+ }
+ ELSE
+ {
+ lastnz2 = lastnz;
+ }
+
+ IF (mode < 0)
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = L_abs(xq[a1_i]);
+ b1 = L_abs(xq[b1_i]);
+ ab_max = L_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (L_sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1));
+ }
+ ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ nbits32 = L_add(nbits32, 2 << SYM_BITS_Q);
+ a1_msb = L_shr_pos_pos(a1, 1);
+ b1_msb = L_shr_pos_pos(b1, 1);
+ msb = L_add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(maxlevs, sub(norm_l(ab_max), 8));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1));
+ a1_msb = L_shr(a1, levmax);
+ b1_msb = L_shr(b1, levmax);
+ msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+ ELSE IF (mode == 0)
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = L_abs(xq[a1_i]);
+ b1 = L_abs(xq[b1_i]);
+ ab_max = L_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (L_sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1));
+ }
+ ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ nbits32 = L_add(nbits32, 2 << SYM_BITS_Q);
+ a1_msb = L_shr_pos_pos(a1, 1);
+ b1_msb = L_shr_pos_pos(b1, 1);
+ msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(maxlevs, sub(norm_l(ab_max), 8));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1));
+ a1_msb = L_shr(a1, levmax);
+ b1_msb = L_shr(b1, levmax);
+ msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+ ELSE
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = L_abs(xq[a1_i]);
+ b1 = L_abs(xq[b1_i]);
+ ab_max = L_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (L_sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1));
+ }
+ ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ a1_msb = L_shr_pos_pos(a1, 1);
+ b1_msb = L_shr_pos_pos(b1, 1);
+ msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ nbits_lsb = add(nbits_lsb, 2);
+ if (L_sub(a1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (L_sub(b1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(maxlevs, sub(norm_l(ab_max), 8));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1));
+ a1_msb = L_shr(a1, levmax);
+ b1_msb = L_shr(b1, levmax);
+ msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ a1_msb = L_shr_pos(a1, 1);
+ b1_msb = L_shr_pos(b1, 1);
+ if (a1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ nbits_lsb = add(nbits_lsb, 2);
+ if (L_sub(a1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (L_sub(b1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+
+ /* Number of consumed bits */
+ nbits32 = L_add(nbits32, target32);
+ totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1);
+ IF (mode > 0)
+ {
+ totBits = add(totBits, nbits_lsb);
+ }
+ IF (nBits != NULL)
+ {
+ *nBits = totBits;
+ }
+ IF (mode >= 0)
+ {
+ nbits232 = L_add(nbits232, target32);
+ *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1);
+ }
+ ELSE
+ {
+ *nBits2 = *nBits;
+ move16();
+ }
+ IF (mode > 0)
+ {
+ *nBits2 = add(*nBits2, nbits_lsb);
+ }
+ *lastnzout = lastnz2;
+
+ /* Truncation of high frequency coefficients */
+ IF (lastnz > lastnz2)
+ {
+ basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq));
+ }
+
+ /* Truncation of LSBs */
+ test();
+ IF (mode > 0 && sub(totBits, target) > 0)
+ {
+ *lsbMode = 1;
+ move16();
+ }
+ ELSE
+ {
+ *lsbMode = 0;
+ move16();
+ }
+
+# ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+# endif
+}
+
+# else /* ENABLE_HR_MODE */
+
+void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt, Word16 target,
+ Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout,
+ Word16 *codingdata, Word16 *lsbMode, Word16 mode
+)
+{
+
+ Word16 a1, b1, a1_i, b1_i;
+ Word16 t, lev1;
+ Word16 lastnz, lastnz2;
+ Word16 rateFlag;
+ Word32 nbits32, nbits232, target32;
+ Word16 nt_half;
+ Word16 c, ab_max, msb, a1_msb, b1_msb, levmax;
+ Word16 s;
+ Word16 totBits, nbits_lsb;
+ Counter k, lev;
+ Word16 tmp16;
+ Word32 offs32;
+ Counter i;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct {
+ Word16 a1, b1, a1_i, b1_i;
+ Word16 t, lev1;
+ Word16 lastnz, lastnz2;
+ Word16 rateFlag;
+ Word32 nbits32, nbits232;
+ Word16 nt_half;
+ Word16 c, ab_max, msb, a1_msb, b1_msb, levmax;
+ Counter k, lev, i;
+ Word16 s;
+ Word16 tmp16;
+ Word32 offs32, target32;
+ Word16 totBits, nbits_lsb;
+ }));
+#endif
+
+ /* Quantization */
+ gain = Inv16_lc3plus(gain, &gain_e);
+ s = sub(add(x_e, gain_e), 15);
+ s = s_max(s_min(s, 15), -15);
+
+ FOR (i = 0; i < nt; i++)
+ {
+ offs32 = Mpy_32_16_lc3plus(L_abs(x[i]), gain); /* multiply */
+ offs32 = L_shl(offs32, s); /* convert to 15Q16 */
+ tmp16 = extract_h(L_add(offs32, 0x00006000)); /* add offset and truncate */
+ Word16 x_sign = (Word16) L_shr(x[i], 31);
+ xq[i] = sub(s_xor(tmp16, x_sign), x_sign);
+ move16();
+ /*
+ Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375
+ -> 0.375 = 0x00006000 in 15Q16
+ */
+ }
+
+ /* Rate flag */
+ rateFlag = 0;
+ move16();
+ if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0)
+ {
+ rateFlag = 2 << NBITS_CONTEXT;
+ move16();
+ }
+
+ /* Init */
+ nt_half = shr_pos(nt, 1);
+ c = 0;
+ move16();
+ t = 0;
+ move16();
+ a1_i = 0;
+ move16();
+ b1_i = 1;
+ move16();
+ target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q);
+ nbits32 = L_negate(target32);
+ nbits232 = 0;
+ move32();
+ nbits_lsb = 0;
+ move16();
+ IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0)
+ {
+ mode = 1;
+ move16();
+ }
+
+ /* Find last non-zero tuple */
+ lastnz = find_last_nz_pair(xq, nt);
+ IF (mode >= 0)
+ {
+ lastnz2 = 2;
+ }
+ ELSE
+ {
+ lastnz2 = lastnz;
+ }
+
+ IF (mode < 0)
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = abs_s(xq[a1_i]);
+ b1 = abs_s(xq[b1_i]);
+ ab_max = s_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = add(a1, shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1));
+ }
+ ELSE IF (sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ nbits32 = L_add(nbits32, 2 << SYM_BITS_Q);
+ a1_msb = shr_pos_pos(a1, 1);
+ b1_msb = shr_pos_pos(b1, 1);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(13, norm_s(ab_max));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1));
+ a1_msb = shr(a1, levmax);
+ b1_msb = shr(b1, levmax);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+ ELSE IF (mode == 0)
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = abs_s(xq[a1_i]);
+ b1 = abs_s(xq[b1_i]);
+ ab_max = s_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = add(a1, shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1));
+ }
+ ELSE IF (sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ nbits32 = L_add(nbits32, 2 << SYM_BITS_Q);
+ a1_msb = shr_pos_pos(a1, 1);
+ b1_msb = shr_pos_pos(b1, 1);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(13, norm_s(ab_max));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1));
+ a1_msb = shr(a1, levmax);
+ b1_msb = shr(b1, levmax);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+ ELSE
+ {
+ /* Main Loop through the 2-tuples */
+ FOR (k = 0; k < lastnz; k += 2)
+ {
+
+ /* Get context */
+ t = add(c, rateFlag);
+ if (sub(k, nt_half) > 0)
+ {
+ t = add(t, 1 << NBITS_CONTEXT);
+ }
+ codingdata[0] = t;
+ move16();
+
+ /* Init current 2-tuple encoding */
+ a1 = abs_s(xq[a1_i]);
+ b1 = abs_s(xq[b1_i]);
+ ab_max = s_max(a1, b1);
+
+ IF (ab_max == 0)
+ {
+ codingdata[1] = -1;
+ move16();
+ codingdata[2] = 0;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]);
+ c = add(shl_pos(s_and(c, 0xf), 4), 1);
+ }
+ ELSE IF (sub(ab_max, A_THRES) < 0)
+ {
+ codingdata[1] = 0;
+ move16();
+ msb = add(a1, shl_pos(b1, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]);
+ if (a1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1 != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1));
+ }
+ ELSE IF (sub(ab_max, 2 * A_THRES) < 0)
+ {
+ codingdata[1] = 1;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]);
+ a1_msb = shr_pos_pos(a1, 1);
+ b1_msb = shr_pos_pos(b1, 1);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]);
+ if (a1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ nbits_lsb = add(nbits_lsb, 2);
+ if (sub(a1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (sub(b1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1));
+ }
+ ELSE
+ {
+ levmax = sub(13, norm_s(ab_max));
+ codingdata[1] = levmax;
+ move16();
+ FOR (lev = 0; lev < levmax; lev++)
+ {
+ lev1 = s_min(lev, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]);
+ }
+ nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1));
+ a1_msb = shr(a1, levmax);
+ b1_msb = shr(b1, levmax);
+ msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT));
+ codingdata[2] = msb;
+ move16();
+ lev1 = s_min(levmax, 3);
+ nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]);
+ a1_msb = shr_pos(a1, 1);
+ b1_msb = shr_pos(b1, 1);
+ if (a1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ if (b1_msb != 0)
+ {
+ nbits32 = L_add(nbits32, 1 << SYM_BITS_Q);
+ }
+ nbits_lsb = add(nbits_lsb, 2);
+ if (sub(a1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (sub(b1, 1) == 0)
+ {
+ nbits_lsb = add(nbits_lsb, 1);
+ }
+ if (nbits32 <= 0)
+ {
+ lastnz2 = add(k, 2);
+ }
+ if (nbits32 <= 0)
+ {
+ nbits232 = nbits32;
+ move32();
+ }
+ c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3)));
+ }
+
+ a1_i += 2;
+ b1_i += 2;
+ codingdata += 3;
+
+ } /* end of the 2-tuples loop */
+ }
+
+ /* Number of consumed bits */
+ nbits32 = L_add(nbits32, target32);
+ totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1);
+ IF (mode > 0)
+ {
+ totBits = add(totBits, nbits_lsb);
+ }
+ IF (nBits != NULL)
+ {
+ *nBits = totBits;
+ }
+ IF (mode >= 0)
+ {
+ nbits232 = L_add(nbits232, target32);
+ *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1);
+ }
+ ELSE
+ {
+ *nBits2 = *nBits;
+ move16();
+ }
+ IF (mode > 0)
+ {
+ *nBits2 = add(*nBits2, nbits_lsb);
+ }
+ *lastnzout = lastnz2;
+
+ /* Truncation of high frequency coefficients */
+ IF (lastnz > lastnz2)
+ {
+ basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq));
+ }
+
+ /* Truncation of LSBs */
+ test();
+ IF (mode > 0 && sub(totBits, target) > 0)
+ {
+ *lsbMode = 1;
+ move16();
+ }
+ ELSE
+ {
+ *lsbMode = 0;
+ move16();
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+# endif /* ENABLE_HR_MODE */
diff --git a/lib_lc3plus/reorder_bitstream_fx.c b/lib_lc3plus/reorder_bitstream_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..281eef325c921bc0bea706bd50da2dcd83761437
--- /dev/null
+++ b/lib_lc3plus/reorder_bitstream_fx.c
@@ -0,0 +1,56 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "defines.h"
+
+#include "constants.h"
+#include "functions.h"
+
+
+void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer)
+{
+ Word16 block_bytes;
+ UWord8 * bytes_tmp;
+
+#ifdef DYNMEM_COUNT
+ struct _dynmem
+ {
+ Word16 block_bits, block_bytes;
+ UWord8 * bytes_tmp;
+ };
+ Dyn_Mem_In("processReorderBitstream_fx", sizeof(struct _dynmem));
+#endif
+
+ bytes_tmp = (UWord8 *)scratchAlign(scratchBuffer, 0); /* Size = LC3PLUS_MAX_BYTES */
+
+ if (n_pccw == 0)
+ {
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return;
+ }
+
+ assert(b_left >= 0);
+
+ /* set block size in bits and full bytes */
+ block_bytes = shr_sat(add(n_pc, 1), 1);
+
+ /* rearrange bitstream */
+ basop_memmove(&bytes_tmp[0], &bytes[b_left], block_bytes * sizeof(UWord8));
+ basop_memmove(&bytes_tmp[block_bytes], &bytes[0], b_left * sizeof(UWord8));
+
+ basop_memmove(&bytes[0], &bytes_tmp[0], add(block_bytes, b_left) * sizeof(UWord8));
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+
diff --git a/lib_lc3plus/resamp12k8_fx.c b/lib_lc3plus/resamp12k8_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..a54f6bc292028066fc378cee596208282d02c88d
--- /dev/null
+++ b/lib_lc3plus/resamp12k8_fx.c
@@ -0,0 +1,121 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[],
+ Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx,
+ Word16 frame_dms, Word8 *scratchBuffer
+ , Word16 bps
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 * buf;
+ Word16 index_int, index_frac, len_12k8;
+ Word16 resamp_upfac, resamp_off_int, resamp_off_frac, resamp_delay;
+ const Word16 *resamp_filt;
+ const Word16 *filt_coeff;
+ Word16 * filt_input;
+ Word32 filt_output, mem_50_0, mem_50_1;
+ Counter n, m;
+ Word32 L_tmp;
+ );
+
+ buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * (MAX_LEN + MAX_LEN / 8) bytes */
+
+ /* resamp parameters : {upsample-factor, 120 / upsample-factor, down_sample_int_part, down_sample_frac_part }
+ upsample is to 384 kHz. upsample-facor = 192000 / samp-freq
+ Fractional downsample parameters are calculated from : downsample samp-freq to 128000
+ At 48000 sampling frequency:
+ upsample-factor = 192000 / 48000 = 4
+ 120 / upsample-factor = 120 / 4 = 30
+ downsample-ratio = 48000 / 12800 = 3.75
+ down_sample_int_part = 3
+ down_sample_frac_part = int(0.75 * upsample-factor ) = 0.75 * 4 = 3
+ */
+ resamp_upfac = resamp_params[fs_idx][0]; move16();
+ resamp_delay = resamp_params[fs_idx][1]; move16();
+ resamp_off_int = resamp_params[fs_idx][2]; move16();
+ resamp_off_frac = resamp_params[fs_idx][3]; move16();
+ resamp_filt = resamp_filts[fs_idx]; move16();
+
+ len_12k8 = LEN_12K8 / 4 * (frame_dms / 25); move16();
+ *y_len = len_12k8; move16();
+
+ /* Init Input Buffer */
+ basop_memmove(buf, mem_in, mem_in_len * sizeof(Word16));
+ basop_memmove(&buf[mem_in_len], x, x_len * sizeof(Word16));
+ basop_memmove(mem_in, &buf[x_len], mem_in_len * sizeof(Word16));
+
+ /* Init Input Indices */
+ index_int = 1; move16();
+ index_frac = 0; move16();
+
+ /* Resampling */
+ FOR (n = 0; n < len_12k8; n++)
+ {
+ /* Init Filtering */
+ filt_input = &buf[index_int];
+ filt_coeff = &resamp_filt[index_frac * resamp_delay * 2];
+
+/* Perform Filtering */
+ filt_output = L_mult0(*filt_input, *filt_coeff);
+ FOR (m = 1; m < resamp_delay * 2; m++)
+ {
+ filt_coeff++;
+ filt_input++;
+ if (*filt_coeff)
+ {
+ filt_output = L_mac0(filt_output, *filt_input, *filt_coeff);
+ }
+ }
+ y[n] = round_fx(filt_output); move16();
+
+ /* Update Input Indices */
+ index_int = add(index_int, resamp_off_int);
+ index_frac = add(index_frac, resamp_off_frac);
+ IF (sub(resamp_upfac, index_frac) <= 0)
+ {
+ index_int = add(index_int, 1);
+ index_frac = sub(index_frac, resamp_upfac);
+ }
+ }
+
+ /* High Pass Filtering (-3dB at 50Hz) */
+ mem_50_0 = mem_50[0]; move32();
+ mem_50_1 = mem_50[1]; move32();
+
+ FOR (n = 0; n < len_12k8; n++)
+ {
+ filt_output = L_mac0_sat(mem_50_0, highpass50_filt_num[0], y[n]);
+ L_tmp = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[0]), highpass50_filt_num[1], y[n]);
+
+ IF (sub(bps, 24) == 0)
+ {
+ mem_50_0 = L_shl_sat(L_add_sat(L_shr_pos(mem_50_1,1), L_tmp), 1);
+ } ELSE
+ {
+ mem_50_0 = L_add_sat(mem_50_1, L_shl_sat(L_tmp, 1));
+ }
+
+ mem_50_1 = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[1]), highpass50_filt_num[2], y[n]);
+ y[n] = round_fx_sat(filt_output); move16();
+ }
+ mem_50[0] = mem_50_0; move32();
+ mem_50[1] = mem_50_1; move32();
+
+/* Output Buffer */
+ basop_memmove(buf, mem_out, mem_out_len * sizeof(Word16));
+ basop_memmove(&buf[mem_out_len], y, len_12k8 * sizeof(Word16));
+ basop_memmove(y, buf, (*y_len + 1) * sizeof(Word16));
+ basop_memmove(mem_out, &buf[len_12k8], mem_out_len * sizeof(Word16));
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/residual_coding_fx.c b/lib_lc3plus/residual_coding_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..2cb6c791f590f5d75300b52aa3d25cd92b78f5d7
--- /dev/null
+++ b/lib_lc3plus/residual_coding_fx.c
@@ -0,0 +1,238 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE
+
+void processResidualCoding_fx(Word16 x_e, Word32 x[],
+ Word32 xq[], Word32 gain,
+ Word16 gain_e, Word16 L_spec,
+ Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits
+ , Word16 hrmode
+)
+{
+
+ Counter i;
+ Word16 s, n, m;
+ Word32 L_tmp;
+ Word16 iter = 0;
+ Counter idx;
+ Word16 N_nz = 0;
+ Word16 n1, n2;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processResidualCoding_fx", sizeof(struct {
+ Counter i;
+ Word16 s, n, m;
+ Word32 L_tmp;
+ Word16 iter;
+ Counter idx;
+ Word16 N_nz;
+ Word16 *nz_idx;
+ Word16 n1, n2;
+ }));
+#endif
+
+ n = 0;
+ move16();
+
+ IF (hrmode)
+ {
+ m = add(sub(targetBits, nBits), 14);
+ assert(m <= (MAX_RESBITS_LEN << RESBITS_PACK_SHIFT));
+ }
+ ELSE
+ {
+ m = add(sub(targetBits, nBits), 4);
+ if (m > L_spec)
+ {
+ m = L_spec;
+ }
+ }
+
+ basop_memset(resBits, 0, sizeof(*resBits)*((m + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT));
+
+ s = sub(add(15, gain_e), x_e);
+
+ IF(hrmode)
+ {
+ /*
+ x = xval * 2^(31 - x_e)
+ gain = gainval * 2^(15 - gain_e)
+
+ To bring gain to the same q of x :
+
+ gain (in_Qx_e) = gain * 2^(16 + gain_e - x_e)
+
+ gain*offset (in Qx_e) = gain (in_Qx_e) * 0.25 = gain (in_Qx_e) / 4 = gain * 2^(16 - 2 + gain_e - x_e)
+ */
+ Word16 shift_val;
+ shift_val = sub(sub(gain_e, x_e), 2);
+
+ Word32 gain_offset;
+
+ IF (shift_val <= -32)
+ gain_offset = 0;
+ ELSE
+ {
+ gain_offset = L_shl_sat(gain, shift_val);
+ }
+
+ Word16 exit_iter = 0;
+
+ Word16 nz_idx[MAX_LEN];
+
+ /* enumerate non-zero coefficients */
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (xq[i])
+ {
+ nz_idx[N_nz] = i; move16();
+ N_nz = add(N_nz, 1);
+ }
+ }
+
+ s = sub(31, sub(x_e, gain_e));
+ FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++)
+ {
+ FOR (i = 0; i < N_nz; i++)
+ {
+ idx = nz_idx[i];
+
+ L_tmp = L_sub(x[idx], Mpy_32_32_lc3plus(L_shl(xq[idx], s), gain));
+
+ IF (L_tmp >= 0)
+ {
+ n1 = shr(n, RESBITS_PACK_SHIFT);
+ n2 = s_and(n, RESBITS_PACK_MASK);
+ resBits[n1] = (UWord8)s_or(resBits[n1], shl(1, n2));
+ move16();
+ x[idx] = L_sub(x[idx], gain_offset);
+ move16();
+ }
+ ELSE
+ {
+ move16();
+ x[idx] = L_add(x[idx], gain_offset);
+ move16();
+ }
+ n = add(n, 1);
+ IF (sub(n, m) == 0)
+ {
+ exit_iter = 1;
+ BREAK;
+ }
+ }
+ gain_offset = L_shr(gain_offset, 1); /* offset *= 0.5 */
+
+ IF (exit_iter)
+ {
+ BREAK;
+ }
+ }
+ }
+ ELSE
+ {
+ s = add(s, 16);
+ gain = round_fx(gain);
+
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (xq[i] != 0)
+ {
+ L_tmp = L_sub(x[i], Mpy_32_16_lc3plus(L_shl(xq[i], s), gain));
+ if (L_tmp >= 0)
+ {
+ n1 = shr(n, RESBITS_PACK_SHIFT);
+ n2 = s_and(n, RESBITS_PACK_MASK);
+ resBits[n1] = (UWord8) s_or(resBits[n1], shl(1, n2));
+ move16();
+ }
+ n = add(n, 1);
+ IF (sub(n, m) == 0)
+ {
+ BREAK;
+ }
+ }
+ }
+ }
+ *numResBits = n;
+ move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+#else
+
+void processResidualCoding_fx(Word16 x_e, Word32 x[],
+ Word16 xq[],
+ Word16 gain, Word16 gain_e, Word16 L_spec,
+ Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits
+)
+{
+
+ Counter i;
+ Word16 s, n, m;
+ Word32 L_tmp;
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processResidualCoding_fx", sizeof(struct {
+ Counter i;
+ Word16 s, n, m;
+ Word32 L_tmp;
+ }));
+#endif
+
+ n = 0;
+ move16();
+ {
+ m = add(sub(targetBits, nBits), 4);
+ if (m > L_spec)
+ {
+ m = L_spec;
+ }
+ }
+
+
+ s = sub(add(15, gain_e), x_e);
+ {
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (xq[i] != 0)
+ {
+ L_tmp = L_sub(x[i], L_shl(L_mult(xq[i], gain), s));
+ if (L_tmp < 0)
+ {
+ resBits[n] = 0;
+ move16();
+ }
+ if (L_tmp >= 0)
+ {
+ resBits[n] = 1;
+ move16();
+ }
+ n = add(n, 1);
+ IF (sub(n, m) == 0)
+ {
+ BREAK;
+ }
+ }
+ }
+ }
+ *numResBits = n;
+ move16();
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+#endif
diff --git a/lib_lc3plus/residual_decoding_fx.c b/lib_lc3plus/residual_decoding_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..686398cdd89fd16444127a86ff9a1b45e773854b
--- /dev/null
+++ b/lib_lc3plus/residual_decoding_fx.c
@@ -0,0 +1,207 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+#ifdef ENABLE_HR_MODE /* HRMODE enables packing of residual bits */
+
+void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+)
+{
+
+ Counter i;
+ Word32 fac_m, fac_p;
+ Word16 s, bits;
+ Word32 tmp;
+ Counter idx;
+ Word16 N_nz = 0;
+ Word16 iter;
+ Word32 fac_hr;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct {
+ Counter i;
+ Word32 fac_m, fac_p;
+ Word16 s, bits;
+ Word32 tmp;
+ Counter idx;
+ Word16 N_nz;
+ Word16 *nz_idx;
+ Word16 iter;
+ }));
+#endif
+
+ tmp = 0;
+ s = sub(x_e, 1);
+ s = s_min(s, 31);
+
+ IF (hrmode)
+ {
+ fac_hr = L_shr(0x10000000, s); /* 0.25 in 1Q30 */
+ }
+ ELSE
+ {
+ fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */
+ fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */
+ }
+
+ bits = 0;
+ move16();
+
+ Word16 nz_idx[MAX_LEN];
+
+ IF (hrmode)
+ {
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (x[i])
+ {
+ nz_idx[N_nz] = i; move16();
+ N_nz = add(N_nz, 1);
+ }
+ }
+ FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++)
+ {
+ IF (sub(bits, resQBits) >= 0)
+ {
+ BREAK;
+ }
+ FOR (i = 0; i < N_nz; i++)
+ {
+ idx = nz_idx[i]; move16();
+
+ IF (sub(bits, resQBits) >= 0)
+ {
+ BREAK;
+ }
+
+ IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK)))))
+ {
+ tmp = L_sub_sat(x[idx], fac_hr);
+ }
+ ELSE
+ {
+ tmp = L_add_sat(x[idx], fac_hr);
+ }
+ x[idx] = tmp;
+ move32();
+ bits = add(bits, 1);
+ }
+ fac_hr = L_shr(fac_hr, 1);
+ }
+ }
+ ELSE
+ {
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (sub(bits, resQBits) >= 0)
+ {
+ BREAK;
+ }
+
+ IF (x[i] != 0)
+ {
+ IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK)))))
+ {
+ if (x[i] > 0)
+ tmp = L_sub(x[i], fac_m);
+ if (x[i] < 0)
+ tmp = L_sub(x[i], fac_p);
+ }
+ ELSE
+ {
+ if (x[i] > 0)
+ tmp = L_add(x[i], fac_p);
+ if (x[i] < 0)
+ tmp = L_add(x[i], fac_m);
+ }
+ x[i] = tmp;
+ move32();
+ bits = add(bits, 1);
+ }
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+#else
+
+void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits
+)
+{
+
+ Counter i;
+ Word32 fac_m, fac_p;
+ Word16 s, bits;
+ Word32 tmp;
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct {
+ Counter i;
+ Word32 fac_m, fac_p;
+ Word16 s, bits;
+ Word32 tmp;
+ }));
+#endif
+
+ tmp = 0;
+ s = sub(x_e, 1);
+ s = s_min(s, 31);
+
+ {
+ fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */
+ fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */
+ }
+
+ bits = 0;
+ move16();
+
+ {
+ FOR (i = 0; i < L_spec; i++)
+ {
+ IF (sub(bits, resQBits) >= 0)
+ {
+ BREAK;
+ }
+
+ IF (x[i] != 0)
+ {
+ IF (prm[bits] == 0)
+ {
+ if (x[i] > 0)
+ tmp = L_sub(x[i], fac_m);
+ if (x[i] < 0)
+ tmp = L_sub(x[i], fac_p);
+ }
+ ELSE
+ {
+ if (x[i] > 0)
+ tmp = L_add(x[i], fac_p);
+ if (x[i] < 0)
+ tmp = L_add(x[i], fac_m);
+ }
+ x[i] = tmp;
+ move32();
+ bits = add(bits, 1);
+ }
+ }
+ }
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+#endif
diff --git a/lib_lc3plus/rom_basop_util.c b/lib_lc3plus/rom_basop_util.c
new file mode 100644
index 0000000000000000000000000000000000000000..e37b4bfad4e49aede655f3c95d07f09a95b11489
--- /dev/null
+++ b/lib_lc3plus/rom_basop_util.c
@@ -0,0 +1,2904 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "rom_basop_util.h"
+#include "basop_util_lc3plus.h"
+#include "functions.h"
+
+
+/* clang-format off */
+# ifdef ENABLE_HR_MODE
+# define STC(x) (x)
+# define WTC(x) (x)
+# define STCP(a, b) {{STC(a), STC(b)}}
+# define WTCP(a, b) {{WTC(a), WTC(b)}}
+# else
+# define STC(x) WORD322WORD16(x)
+# define WTC(x) WORD322WORD16(x)
+# define STCP(a, b) {{STC(a), STC(b)}}
+# define WTCP(a, b) {{WTC(a), WTC(b)}}
+# endif
+/* clang-format on */
+
+/**
+ * \brief Lookup-Table for binary logarithm
+ */
+RAM_ALIGN const Word16 ldCoeff_lc3plus[7] = {-32768, -16384, -10923, -8192, -6554, -5461, -4681};
+
+/**
+ \brief Lookup-Table for binary power algorithm
+
+ This table is used for lookup 2^x with
+ x in range [0...1.0[ in steps of 1/32
+*/
+const UWord32 exp2_tab_long_lc3plus[32] = {
+ 0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6, 0x48E1E9BA, 0x4A7A77D4,
+ 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182, 0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1,
+ 0x5A82799A, 0x5C7DD7A4, 0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9,
+ 0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE, 0x7A92BE8B, 0x7D41D96E,
+};
+
+/**
+ \brief Lookup-Table for binary power algorithm
+
+ This table is used for lookup 2^x with
+ x in range [0...1/32[ in steps of 1/1024
+*/
+const UWord32 exp2w_tab_long_lc3plus[32] = {
+ 0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4, 0x4042AD6D, 0x404DD113,
+ 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300, 0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6,
+ 0x40B268FA, 0x40BD9FFF, 0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA,
+ 0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B, 0x41501CA0, 0x415B6EFB,
+};
+
+/**
+ \brief Lookup-Table for binary power algorithm
+
+ This table is used for lookup 2^x with
+ x in range [0...1/1024[ in steps of 1/32768
+*/
+const UWord32 exp2x_tab_long_lc3plus[32] = {
+ 0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3, 0x4002145F, 0x40026D1B,
+ 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011, 0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E,
+ 0x40058BCE, 0x4005E48F, 0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F,
+ 0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0, 0x400A6688, 0x400ABF4F,
+};
+
+/* square root tables */
+const Word32 SqrtTable_lc3plus[32] = {
+ /* Q31 */
+ 0x5A82D429, 0x5BEA10FE, 0x5D4BE6E5, 0x5EA89270, 0x60004BE2, 0x615347A1, 0x62A1B68C, 0x63EBC651,
+ 0x6531A1B5, 0x667370D4, 0x67B1595F, 0x68EB7EC8, 0x6A220277, 0x6B5503F0, 0x6C84A0F9, 0x6DB0F5BD,
+ 0x6EDA1CE9, 0x70002FC7, 0x7123465A, 0x72437773, 0x7360D8C5, 0x747B7EFA, 0x75937DC4, 0x76A8E7EB,
+ 0x77BBCF60, 0x78CC4545, 0x79DA5A00, 0x7AE61D3E, 0x7BEF9E07, 0x7CF6EAC2, 0x7DFC113F, 0x7EFF1EC0,
+};
+
+const Word16 SqrtDiffTable_lc3plus[32] = {
+ /* Q21 */
+ 0x59CF, 0x5875, 0x572B, 0x55EE, 0x54BF, 0x539C, 0x5284, 0x5177, 0x5074, 0x4F7A, 0x4E89,
+ 0x4DA1, 0x4CC0, 0x4BE7, 0x4B15, 0x4A4A, 0x4985, 0x48C6, 0x480C, 0x4758, 0x46AA, 0x4600,
+ 0x455B, 0x44BA, 0x441D, 0x4385, 0x42F1, 0x4260, 0x41D3, 0x414A, 0x40C3, 0x4040,
+};
+
+const Word32 ISqrtTable_lc3plus[32] = {
+ /* Q31 */
+ 0x7FFE7F85, 0x7E0A4E25, 0x7C2C56C7, 0x7A63002C, 0x78ACD922, 0x7708939D, 0x75750088, 0x73F10C2D,
+ 0x727BBB1A, 0x71142774, 0x6FB97EA5, 0x6E6AFF54, 0x6D27F79D, 0x6BEFC388, 0x6AC1CBA4, 0x699D83DA,
+ 0x68826A53, 0x6770068E, 0x6665E882, 0x6563A7DF, 0x6468E364, 0x63754043, 0x62886999, 0x61A20FEE,
+ 0x60C1E8C8, 0x5FE7AE45, 0x5F131EBE, 0x5E43FC76, 0x5D7A0D4F, 0x5CB51A81, 0x5BF4F061, 0x5B395E26,
+};
+
+const Word16 ISqrtDiffTable_lc3plus[32] = {
+ /* Q21 */
+ 0x7D0C, 0x777E, 0x7256, 0x6D8A, 0x6911, 0x64E5, 0x60FD, 0x5D54, 0x59E5, 0x56AA, 0x53A0,
+ 0x50C2, 0x4E0D, 0x4B7E, 0x4912, 0x46C6, 0x4499, 0x4288, 0x4090, 0x3EB1, 0x3CE9, 0x3B36,
+ 0x3996, 0x380A, 0x368F, 0x3524, 0x33C9, 0x327C, 0x313D, 0x300B, 0x2EE5, 0x2DCA,
+};
+
+/* 1/x tables */
+const Word32 InvTable_lc3plus[32] = {
+ /* Q31 */
+ 0x7FFBFE40, 0x7C1B608E, 0x78752176, 0x750440BA, 0x71C44C49, 0x6EB14D0A, 0x6BC7B6B4, 0x69045A19,
+ 0x6664598A, 0x63E51EE2, 0x61845308, 0x5F3FD698, 0x5D15BB8E, 0x5B043FD0, 0x5909C861, 0x5724DD3C,
+ 0x555425B2, 0x53966532, 0x51EA787F, 0x504F5331, 0x4EC3FD84, 0x4D479267, 0x4BD93DBE, 0x4A783ADC,
+ 0x4923D31D, 0x47DB5CAE, 0x469E3974, 0x456BD608, 0x4443A8D9, 0x43253159, 0x420FF746, 0x41038A01,
+};
+
+#ifdef ENABLE_HR_MODE
+const Word16 InvIntTable[74] = {
+ 32767, 32767, 16384, 10923, 8192, 6554, 5461, 4681, 4096, 3641, 3277, 2979, 2731, 2521, 2341,
+ 2185, 2048, 1928, 1820, 1725, 1638, 1560, 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130,
+ 1092, 1057, 1024, 993, 964, 936, 910, 886, 862, 840, 819, 799, 780, 762, 745,
+ 728, 712, 697, 683, 669, 655, 643, 630, 618, 607, 596, 585, 575, 565, 555,
+ 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468, 462, 455, 449
+};
+#else
+const Word16 InvIntTable[32] = {
+ 0x7FFF, 0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000, 0x0E39, 0x0CCD,
+ 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800, 0x0788, 0x071C, 0x06BD, 0x0666, 0x0618,
+ 0x05D1, 0x0591, 0x0555, 0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421,
+};
+#endif
+
+const Word16 InvDiffTable_lc3plus[32] = {
+ /* Q20 */
+ 0x7C14, 0x74C8, 0x6E1C, 0x67FF, 0x6260, 0x5D33, 0x586C, 0x5400, 0x4FE7, 0x4C19, 0x4890,
+ 0x4543, 0x422F, 0x3F4F, 0x3C9D, 0x3A17, 0x37B8, 0x357E, 0x3365, 0x316B, 0x2F8D, 0x2DCB,
+ 0x2C20, 0x2A8D, 0x290F, 0x27A4, 0x264C, 0x2506, 0x23CF, 0x22A7, 0x218E, 0x2081,
+};
+
+/*
+ Sine tables
+ */
+# ifdef ENABLE_HR_MODE
+const PWord32 SineTable480[] = {
+# else
+const PWord16 SineTable480[] = {
+# endif
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffd315, 0x006b3b9b), STCP(0x7fff4c54, 0x00d676eb),
+ STCP(0x7ffe6bbf, 0x0141b1a5), STCP(0x7ffd3154, 0x01aceb7c), STCP(0x7ffb9d15, 0x02182427),
+ STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff76721, 0x02ee90c8), STCP(0x7ff4c56f, 0x0359c428),
+ STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7fee74a2, 0x0430238f), STCP(0x7feac58d, 0x049b4f00),
+ STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fe25a0f, 0x05719be2), STCP(0x7fdd9dad, 0x05dcbcbe),
+ STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd317b4, 0x06b2f1d2), STCP(0x7fcd4e24, 0x071e0575),
+ STCP(0x7fc72ae2, 0x07891418), STCP(0x7fc0adf2, 0x07f41d72), STCP(0x7fb9d759, 0x085f2137),
+ STCP(0x7fb2a71b, 0x08ca1f1b), STCP(0x7fab1d3d, 0x093516d4), STCP(0x7fa339c5, 0x09a00817),
+ STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f92661d, 0x0a75d60e), STCP(0x7f8975f9, 0x0ae0b22c),
+ STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f76892f, 0x0bb65336), STCP(0x7f6c8c96, 0x0c21178c),
+ STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f578721, 0x0cf68662), STCP(0x7f4c7e54, 0x0d61304e),
+ STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f3560b9, 0x0e3667ad), STCP(0x7f294bfd, 0x0ea0f48c),
+ STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f1016ce, 0x0f75ef33), STCP(0x7f02f66f, 0x0fe05c64),
+ STCP(0x7ef57cea, 0x104abe71), STCP(0x7ee7aa4c, 0x10b5150f), STCP(0x7ed97e9c, 0x111f5ff4),
+ STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7ebc1c31, 0x11f3d164), STCP(0x7eace58a, 0x125df75b),
+ STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e8d6d91, 0x13321c53), STCP(0x7e7d2c54, 0x139c1abf),
+ STCP(0x7e6c9251, 0x14060b68), STCP(0x7e5b9f93, 0x146fee03), STCP(0x7e4a5426, 0x14d9c245),
+ STCP(0x7e38b017, 0x154387e6), STCP(0x7e26b371, 0x15ad3e9a), STCP(0x7e145e42, 0x1616e618),
+ STCP(0x7e01b096, 0x16807e15), STCP(0x7deeaa7a, 0x16ea0646), STCP(0x7ddb4bfc, 0x17537e63),
+ STCP(0x7dc79529, 0x17bce621), STCP(0x7db3860f, 0x18263d36), STCP(0x7d9f1ebd, 0x188f8357),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d7547a7, 0x1961db9b), STCP(0x7d5fd801, 0x19caed29),
+ STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d33f0ca, 0x1a9cd9ac), STCP(0x7d1d7958, 0x1b05b40f),
+ STCP(0x7d06aa16, 0x1b6e7b7a), STCP(0x7cef8315, 0x1bd72fa4), STCP(0x7cd80464, 0x1c3fd045),
+ STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7ca80038, 0x1d10d5c2), STCP(0x7c8f7ade, 0x1d793a0b),
+ STCP(0x7c769e18, 0x1de189a6), STCP(0x7c5d69f7, 0x1e49c447), STCP(0x7c43de8e, 0x1eb1e9a7),
+ STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c0fc22a, 0x1f81f37c), STCP(0x7bf53153, 0x1fe9d75f),
+ STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bbf0aba, 0x20b95bac), STCP(0x7ba3751d, 0x2120fb83),
+ STCP(0x7b8788ba, 0x2188841a), STCP(0x7b6b45a5, 0x21eff528), STCP(0x7b4eabf1, 0x22574e65),
+ STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7b1474fd, 0x2325b847), STCP(0x7af6d7e6, 0x238cc85d),
+ STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aba9ae6, 0x245a9d65), STCP(0x7a9bfb27, 0x24c161c7),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5db997, 0x258e9ce0), STCP(0x7a3e17f2, 0x25f51307),
+ STCP(0x7a1e2082, 0x265b6e8a), STCP(0x79fdd35c, 0x26c1af22), STCP(0x79dd3098, 0x2727d486),
+ STCP(0x79bc384d, 0x278dde6e), STCP(0x799aea92, 0x27f3cc94), STCP(0x7979477d, 0x28599eb0),
+ STCP(0x79574f28, 0x28bf547b), STCP(0x793501a9, 0x2924edac), STCP(0x79125f19, 0x298a69fc),
+ STCP(0x78ef678f, 0x29efc925), STCP(0x78cc1b26, 0x2a550adf), STCP(0x78a879f4, 0x2aba2ee4),
+ STCP(0x78848414, 0x2b1f34eb), STCP(0x7860399e, 0x2b841caf), STCP(0x783b9aad, 0x2be8e5e8),
+ STCP(0x7816a759, 0x2c4d9050), STCP(0x77f15fbc, 0x2cb21ba0), STCP(0x77cbc3f2, 0x2d168792),
+ STCP(0x77a5d413, 0x2d7ad3de), STCP(0x777f903c, 0x2ddf0040), STCP(0x7758f886, 0x2e430c6f),
+ STCP(0x77320d0d, 0x2ea6f827), STCP(0x770acdec, 0x2f0ac320), STCP(0x76e33b3f, 0x2f6e6d16),
+ STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x76931bae, 0x30355cdd), STCP(0x766a8f04, 0x3098a223),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x76187c77, 0x315ec617), STCP(0x75eef6ce, 0x31c1a43b),
+ STCP(0x75c51e61, 0x32245f72), STCP(0x759af34c, 0x3286f779), STCP(0x757075ac, 0x32e96c09),
+ STCP(0x7545a5a0, 0x334bbcde), STCP(0x751a8346, 0x33ade9b3), STCP(0x74ef0ebc, 0x340ff242),
+ STCP(0x74c34820, 0x3471d647), STCP(0x74972f92, 0x34d3957e), STCP(0x746ac52f, 0x35352fa1),
+ STCP(0x743e0918, 0x3596a46c), STCP(0x7410fb6b, 0x35f7f39c), STCP(0x73e39c49, 0x36591cea),
+ STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7387ea23, 0x371afcd5), STCP(0x73599760, 0x377bb2e9),
+ STCP(0x732af3a7, 0x37dc420c), STCP(0x72fbff1b, 0x383ca9fb), STCP(0x72ccb9db, 0x389cea72),
+ STCP(0x729d2409, 0x38fd032d), STCP(0x726d3dc6, 0x395cf3e9), STCP(0x723d0734, 0x39bcbc63),
+ STCP(0x720c8075, 0x3a1c5c57), STCP(0x71dba9ab, 0x3a7bd382), STCP(0x71aa82f7, 0x3adb21a1),
+ STCP(0x71790c7e, 0x3b3a4672), STCP(0x71474660, 0x3b9941b1), STCP(0x711530c2, 0x3bf8131c),
+ STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b01790, 0x3cb5376b), STCP(0x707d1443, 0x3d1389cb),
+ STCP(0x7049c203, 0x3d71b14d), STCP(0x701620f5, 0x3dcfadb0), STCP(0x6fe2313c, 0x3e2d7eb1),
+ STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6f79665b, 0x3ee89d86), STCP(0x6f448b7e, 0x3f45ead8),
+ STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ed9eba1, 0x40000000), STCP(0x6ea426ed, 0x405cc754),
+ STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e37b4b6, 0x4115ce38), STCP(0x6e010780, 0x41720d46),
+ STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d92c59b, 0x422a0154), STCP(0x6d5b313b, 0x4285b5d4),
+ STCP(0x6d23501b, 0x42e13ba4), STCP(0x6ceb2261, 0x433c9283), STCP(0x6cb2a837, 0x4397ba32),
+ STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c40cf2c, 0x444d7aff), STCP(0x6c07709b, 0x44a8139e),
+ STCP(0x6bcdc639, 0x45027c0c), STCP(0x6b93d02e, 0x455cb40c), STCP(0x6b598ea3, 0x45b6bb5e),
+ STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ae429ae, 0x466a36f9), STCP(0x6aa90697, 0x46c3aac5),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a31e000, 0x4775fd1f), STCP(0x69f5dcd3, 0x47cedb31),
+ STCP(0x69b98f48, 0x482786dc), STCP(0x697cf78a, 0x487fffe4), STCP(0x694015c3, 0x48d84609),
+ STCP(0x6902ea1d, 0x4930590f), STCP(0x68c574c4, 0x498838b6), STCP(0x6887b5e2, 0x49dfe4c2),
+ STCP(0x6849ada3, 0x4a375cf5), STCP(0x680b5c33, 0x4a8ea111), STCP(0x67ccc1be, 0x4ae5b0da),
+ STCP(0x678dde6e, 0x4b3c8c12), STCP(0x674eb271, 0x4b93327c), STCP(0x670f3df3, 0x4be9a3db),
+ STCP(0x66cf8120, 0x4c3fdff4), STCP(0x668f7c25, 0x4c95e688), STCP(0x664f2f2e, 0x4cebb75c),
+ STCP(0x660e9a6a, 0x4d415234), STCP(0x65cdbe05, 0x4d96b6d3), STCP(0x658c9a2d, 0x4debe4fe),
+ STCP(0x654b2f10, 0x4e40dc79), STCP(0x65097cdb, 0x4e959d08), STCP(0x64c783bd, 0x4eea2670),
+ STCP(0x648543e4, 0x4f3e7875), STCP(0x6442bd7e, 0x4f9292dc), STCP(0x63fff0ba, 0x4fe6756a),
+ STCP(0x63bcddc7, 0x503a1fe5), STCP(0x637984d4, 0x508d9211), STCP(0x6335e611, 0x50e0cbb4),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62add7d6, 0x51869476), STCP(0x626968be, 0x51d92321),
+ STCP(0x6224b495, 0x522b7859), STCP(0x61dfbb8a, 0x527d93e6), STCP(0x619a7dce, 0x52cf758f),
+ STCP(0x6154fb91, 0x53211d18), STCP(0x610f3505, 0x53728a4a), STCP(0x60c92a5a, 0x53c3bcea),
+ STCP(0x6082dbc1, 0x5414b4c1), STCP(0x603c496c, 0x54657194), STCP(0x5ff5738d, 0x54b5f32c),
+ STCP(0x5fae5a55, 0x55063951), STCP(0x5f66fdf5, 0x555643c8), STCP(0x5f1f5ea1, 0x55a6125c),
+ STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e46f0dd, 0x5694148b),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5db55c86, 0x57319135), STCP(0x5d6c2f99, 0x577ff3da),
+ STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cd91140, 0x581c00b3), STCP(0x5c8f203b, 0x5869aa79),
+ STCP(0x5c44ee40, 0x58b71632), STCP(0x5bfa7b82, 0x590443a7), STCP(0x5bafc837, 0x595132a2),
+ STCP(0x5b64d492, 0x599de2ee), STCP(0x5b19a0c8, 0x59ea5454), STCP(0x5ace2d0f, 0x5a36869f),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineTable360[] = {
+# else
+const PWord16 SineTable360[] = {
+# endif
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffb025, 0x008efa17), STCP(0x7ffec095, 0x011df37c),
+ STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffb025f, 0x023be165), STCP(0x7ff833bc, 0x02cad485),
+ STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff0b779, 0x03e8af9e), STCP(0x7fec09e2, 0x04779632),
+ STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe0cfe6, 0x059551f1), STCP(0x7fda4390, 0x062425b6),
+ STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcb4c5a, 0x0741b592), STCP(0x7fc2e18d, 0x07d07044),
+ STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb02dc5, 0x08edc7b7), STCP(0x7fa5e4e0, 0x097c6313),
+ STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f8f7558, 0x0a997597), STCP(0x7f834ecf, 0x0b27eb5c),
+ STCP(0x7f76892e, 0x0bb65336), STCP(0x7f692482, 0x0c44ac72), STCP(0x7f5b20de, 0x0cd2f660),
+ STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f3d3cf3, 0x0def5989), STCP(0x7f2d5cd0, 0x0e7d7162),
+ STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f0bc096, 0x0f996a26), STCP(0x7efa04a7, 0x102749ae),
+ STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ed4b197, 0x1142cb98), STCP(0x7ec11aa4, 0x11d06c96),
+ STCP(0x7eace589, 0x125df75b), STCP(0x7e981261, 0x12eb6b35), STCP(0x7e82a145, 0x1378c774),
+ STCP(0x7e6c9250, 0x14060b68), STCP(0x7e55e59d, 0x1493365f), STCP(0x7e3e9b49, 0x152047ab),
+ STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e0e2e31, 0x163a1a7e), STCP(0x7df50baa, 0x16c6daa6),
+ STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dc0ef43, 0x17e00505), STCP(0x7da5f5a4, 0x186c6ddd),
+ STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d6e2c36, 0x1984e373), STCP(0x7d515cae, 0x1a10eed2),
+ STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d15e8ac, 0x1b28a351), STCP(0x7cf7447e, 0x1bb44b13),
+ STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cb82884, 0x1ccb3237), STCP(0x7c97b108, 0x1d56703b),
+ STCP(0x7c769e17, 0x1de189a5), STCP(0x7c54efdb, 0x1e6c7dc7), STCP(0x7c32a67d, 0x1ef74bf3),
+ STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bec430a, 0x200c73b4), STCP(0x7bc8294c, 0x2096cbf0),
+ STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b7e26a9, 0x21ab01c0), STCP(0x7b583e20, 0x2234ddfa),
+ STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b0a9f8d, 0x234815ba), STCP(0x7ae2e9e3, 0x23d16fe8),
+ STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7a91b2c6, 0x24e39d85), STCP(0x7a6831b9, 0x256c6f9f),
+ STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a1365a4, 0x267d8713), STCP(0x79e81b05, 0x2705cb19),
+ STCP(0x79bc384c, 0x278dde6e), STCP(0x798fbdaf, 0x2815c069), STCP(0x7962ab66, 0x289d7061),
+ STCP(0x793501a8, 0x2924edab), STCP(0x7906c0af, 0x29ac37a0), STCP(0x78d7e8b5, 0x2a334d95),
+ STCP(0x78a879f3, 0x2aba2ee3), STCP(0x787874a6, 0x2b40dae2), STCP(0x7847d908, 0x2bc750e9),
+ STCP(0x7816a758, 0x2c4d9050), STCP(0x77e4dfd1, 0x2cd39870), STCP(0x77b282b3, 0x2d5968a2),
+ STCP(0x777f903b, 0x2ddf003f), STCP(0x774c08aa, 0x2e645ea0), STCP(0x7717ec40, 0x2ee9831f),
+ STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76adf5e5, 0x2ff31bdd), STCP(0x76781c79, 0x30778ed2),
+ STCP(0x7641af3c, 0x30fbc54d), STCP(0x760aae72, 0x317fbeaa), STCP(0x75d31a60, 0x32037a45),
+ STCP(0x759af34b, 0x3286f778), STCP(0x75623979, 0x330a35a1), STCP(0x7528ed31, 0x338d341a),
+ STCP(0x74ef0ebb, 0x340ff242), STCP(0x74b49e5f, 0x34926f74), STCP(0x74799c65, 0x3514ab0d),
+ STCP(0x743e0917, 0x3596a46c), STCP(0x7401e4c0, 0x36185aee), STCP(0x73c52faa, 0x3699cdf1),
+ STCP(0x7387ea22, 0x371afcd4), STCP(0x734a1474, 0x379be6f6), STCP(0x730baeec, 0x381c8bb5),
+ STCP(0x72ccb9da, 0x389cea71), STCP(0x728d358b, 0x391d028b), STCP(0x724d224e, 0x399cd362),
+ STCP(0x720c8074, 0x3a1c5c56), STCP(0x71cb504d, 0x3a9b9cc9), STCP(0x7189922b, 0x3b1a941c),
+ STCP(0x7147465f, 0x3b9941b0), STCP(0x71046d3d, 0x3c17a4e8), STCP(0x70c10717, 0x3c95bd25),
+ STCP(0x707d1442, 0x3d1389cb), STCP(0x70389513, 0x3d910a3c), STCP(0x6ff389de, 0x3e0e3ddb),
+ STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f67d0c0, 0x3f07bc37), STCP(0x6f212384, 0x3f8405bb),
+ STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6e92296d, 0x407baa69), STCP(0x6e49dd44, 0x40f7045f),
+ STCP(0x6e01077f, 0x41720d45), STCP(0x6db7a879, 0x41ecc483), STCP(0x6d6dc08e, 0x42672980),
+ STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cd85779, 0x435afa54), STCP(0x6c8cd70a, 0x43d464fa),
+ STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6bf4403a, 0x44c63bca), STCP(0x6ba72a97, 0x453ea6c7),
+ STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b0b6cbc, 0x462e78f8), STCP(0x6abcc546, 0x46a5df02),
+ STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a1de736, 0x4793a210), STCP(0x69cdb161, 0x4809fdeb),
+ STCP(0x697cf789, 0x487fffe3), STCP(0x692bba13, 0x48f5a767), STCP(0x68d9f964, 0x496af3e1),
+ STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6834eff2, 0x4a547975), STCP(0x67e1a7ff, 0x4ac8b16b),
+ STCP(0x678dde6e, 0x4b3c8c11), STCP(0x673993a8, 0x4bb008d8), STCP(0x66e4c817, 0x4c23272f),
+ STCP(0x668f7c24, 0x4c95e687), STCP(0x6639b03a, 0x4d084651), STCP(0x65e364c3, 0x4d7a45fd),
+ STCP(0x658c9a2d, 0x4debe4fe), STCP(0x653550e1, 0x4e5d22c5), STCP(0x64dd894f, 0x4ecdfec6),
+ STCP(0x648543e3, 0x4f3e7874), STCP(0x642c810b, 0x4fae8f42), STCP(0x63d34136, 0x501e42a5),
+ STCP(0x637984d4, 0x508d9211), STCP(0x631f4c54, 0x50fc7cfa), STCP(0x62c49826, 0x516b02d8),
+ STCP(0x626968be, 0x51d92320), STCP(0x620dbe8a, 0x5246dd48), STCP(0x61b19a00, 0x52b430c8),
+ STCP(0x6154fb90, 0x53211d17), STCP(0x60f7e3b0, 0x538da1ae), STCP(0x609a52d2, 0x53f9be04),
+ STCP(0x603c496c, 0x54657194), STCP(0x5fddc7f3, 0x54d0bbd6), STCP(0x5f7ecedd, 0x553b9c45),
+ STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5ebf77b4, 0x56101d94), STCP(0x5e5f1a90, 0x5679bd6b),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5d9cff82, 0x574bb8e6), STCP(0x5d3b428b, 0x57b41383),
+ STCP(0x5cd91140, 0x581c00b3), STCP(0x5c766c1c, 0x58837ff3), STCP(0x5c13539a, 0x58ea90c3),
+ STCP(0x5bafc836, 0x595132a2), STCP(0x5b4bca6c, 0x59b7650f), STCP(0x5ae75ab8, 0x5a1d278c),
+ STCP(0x5a827999, 0x5a827999),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineTable320[] = {
+# else
+const PWord16 SineTable320[] = {
+# endif
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fff9aef, 0x00a0d951), STCP(0x7ffe6bbf, 0x0141b1a5),
+ STCP(0x7ffc726f, 0x01e287fc), STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff62182, 0x03242abf),
+ STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7feca851, 0x0465b9aa), STCP(0x7fe6bcb0, 0x05067734),
+ STCP(0x7fe00716, 0x05a72ccf), STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd03e23, 0x06e87c3f),
+ STCP(0x7fc72ae2, 0x07891418), STCP(0x7fbd4dda, 0x0829a00c), STCP(0x7fb2a71b, 0x08ca1f1b),
+ STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f8df93c, 0x0aab450d),
+ STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f719611, 0x0bebb66c), STCP(0x7f62368f, 0x0c8bd35e),
+ STCP(0x7f520de6, 0x0d2bdc80), STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f2f6183, 0x0e6baf61),
+ STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f0991c4, 0x0fab272b), STCP(0x7ef57cea, 0x104abe71),
+ STCP(0x7ee09f95, 0x10ea3bfd), STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7eb48bfb, 0x1228e5f8),
+ STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e85580c, 0x13671d3d), STCP(0x7e6c9251, 0x14060b68),
+ STCP(0x7e5304f2, 0x14a4d9f4), STCP(0x7e38b017, 0x154387e6), STCP(0x7e1d93ea, 0x15e21445),
+ STCP(0x7e01b096, 0x16807e15), STCP(0x7de50646, 0x171ec45c), STCP(0x7dc79529, 0x17bce621),
+ STCP(0x7da95d6c, 0x185ae269), STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d6a9ad5, 0x199666a0),
+ STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d28c00c, 0x1ad14938), STCP(0x7d06aa16, 0x1b6e7b7a),
+ STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7c9bc87a, 0x1d450a78),
+ STCP(0x7c769e18, 0x1de189a6), STCP(0x7c50af2b, 0x1e7dd9a4), STCP(0x7c29fbee, 0x1f19f97b),
+ STCP(0x7c02849f, 0x1fb5e836), STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bb14ac5, 0x20ed2e7b),
+ STCP(0x7b8788ba, 0x2188841a), STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b31bbb2, 0x22be8f87),
+ STCP(0x7b05b13d, 0x2359436c), STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aab55ca, 0x248e02cb),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a4df380, 0x25c1db44), STCP(0x7a1e2082, 0x265b6e8a),
+ STCP(0x79ed8cad, 0x26f4c53e), STCP(0x79bc384d, 0x278dde6e), STCP(0x798a23b1, 0x2826b928),
+ STCP(0x79574f28, 0x28bf547b), STCP(0x7923bb01, 0x2957af74), STCP(0x78ef678f, 0x29efc925),
+ STCP(0x78ba5524, 0x2a87a09d), STCP(0x78848414, 0x2b1f34eb), STCP(0x784df4b3, 0x2bb68522),
+ STCP(0x7816a759, 0x2c4d9050), STCP(0x77de9c5b, 0x2ce45589), STCP(0x77a5d413, 0x2d7ad3de),
+ STCP(0x776c4edb, 0x2e110a62), STCP(0x77320d0d, 0x2ea6f827), STCP(0x76f70f05, 0x2f3c9c40),
+ STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x767edfbe, 0x306703bf), STCP(0x7641af3d, 0x30fbc54d),
+ STCP(0x7603c3fd, 0x31903982), STCP(0x75c51e61, 0x32245f72), STCP(0x7585becb, 0x32b83634),
+ STCP(0x7545a5a0, 0x334bbcde), STCP(0x7504d345, 0x33def287), STCP(0x74c34820, 0x3471d647),
+ STCP(0x74810499, 0x35046736), STCP(0x743e0918, 0x3596a46c), STCP(0x73fa5607, 0x36288d03),
+ STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7370cae2, 0x374b5cb9), STCP(0x732af3a7, 0x37dc420c),
+ STCP(0x72e4668f, 0x386ccf2a), STCP(0x729d2409, 0x38fd032d), STCP(0x72552c85, 0x398cdd32),
+ STCP(0x720c8075, 0x3a1c5c57), STCP(0x71c3204c, 0x3aab7fb7), STCP(0x71790c7e, 0x3b3a4672),
+ STCP(0x712e457f, 0x3bc8afa5), STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70969fca, 0x3ce465f3),
+ STCP(0x7049c203, 0x3d71b14d), STCP(0x6ffc32eb, 0x3dfe9ba1), STCP(0x6fadf2fc, 0x3e8b240e),
+ STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ebf12ff, 0x402e694c),
+ STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e1c67c4, 0x4143f379), STCP(0x6dca0d14, 0x41ce1e65),
+ STCP(0x6d770506, 0x4257e166), STCP(0x6d23501b, 0x42e13ba4), STCP(0x6cceeed8, 0x436a2c45),
+ STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c242960, 0x447acd50), STCP(0x6bcdc639, 0x45027c0c),
+ STCP(0x6b76b8d6, 0x4589bdcf), STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ac6a180, 0x4696f710),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a13e7b8, 0x47a27271), STCP(0x69b98f48, 0x482786dc),
+ STCP(0x695e8fe5, 0x48ac2957), STCP(0x6902ea1d, 0x4930590f), STCP(0x68a69e81, 0x49b41533),
+ STCP(0x6849ada3, 0x4a375cf5), STCP(0x67ec1817, 0x4aba2f84), STCP(0x678dde6e, 0x4b3c8c12),
+ STCP(0x672f013f, 0x4bbe71d1), STCP(0x66cf8120, 0x4c3fdff4), STCP(0x666f5ea6, 0x4cc0d5ae),
+ STCP(0x660e9a6a, 0x4d415234), STCP(0x65ad3505, 0x4dc154bb), STCP(0x654b2f10, 0x4e40dc79),
+ STCP(0x64e88926, 0x4ebfe8a5), STCP(0x648543e4, 0x4f3e7875), STCP(0x64215fe5, 0x4fbc8b22),
+ STCP(0x63bcddc7, 0x503a1fe5), STCP(0x6357be2a, 0x50b735f8), STCP(0x62f201ac, 0x5133cc94),
+ STCP(0x628ba8ef, 0x51afe2f6), STCP(0x6224b495, 0x522b7859), STCP(0x61bd253f, 0x52a68bfb),
+ STCP(0x6154fb91, 0x53211d18), STCP(0x60ec3830, 0x539b2af0), STCP(0x6082dbc1, 0x5414b4c1),
+ STCP(0x6018e6eb, 0x548db9cb), STCP(0x5fae5a55, 0x55063951), STCP(0x5f4336a7, 0x557e3292),
+ STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e6b2ca8, 0x566c8f55), STCP(0x5dfe47ad, 0x56e2f15d),
+ STCP(0x5d90ce45, 0x5758ca31), STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cb420e0, 0x5842dd54),
+ STCP(0x5c44ee40, 0x58b71632), STCP(0x5bd529eb, 0x592ac2f7), STCP(0x5b64d492, 0x599de2ee),
+ STCP(0x5af3eee6, 0x5a107561), STCP(0x5a82799a, 0x5a82799a),
+};
+
+
+# ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+ const PWord32 SineTable720[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffec08, 0x00477d17), STCP(0x7fffb025, 0x008efa17),
+ STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffec095, 0x011df37c), STCP(0x7ffe0cea, 0x01656fb4),
+ STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffc2dcf, 0x01f466bf), STCP(0x7ffb025f, 0x023be165),
+ STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff833bc, 0x02cad485), STCP(0x7ff6908a, 0x03124cd1),
+ STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff2d268, 0x03a13a74), STCP(0x7ff0b779, 0x03e8af9e),
+ STCP(0x7fee74a1, 0x0430238f), STCP(0x7fec09e2, 0x04779632), STCP(0x7fe9773c, 0x04bf0771),
+ STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe3da3d, 0x054de566), STCP(0x7fe0cfe6, 0x059551f1),
+ STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fda4390, 0x062425b6), STCP(0x7fd6c192, 0x066b8cc5),
+ STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcf45f6, 0x06fa54c9), STCP(0x7fcb4c5a, 0x0741b592),
+ STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc2e18d, 0x07d07044), STCP(0x7fbe705f, 0x0817ca01),
+ STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb51679, 0x08a675d0), STCP(0x7fb02dc5, 0x08edc7b7),
+ STCP(0x7fab1d3c, 0x093516d4), STCP(0x7fa5e4e0, 0x097c6313), STCP(0x7fa084b4, 0x09c3ac5c),
+ STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f954cee, 0x0a5235b4), STCP(0x7f8f7558, 0x0a997597),
+ STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f834ecf, 0x0b27eb5c), STCP(0x7f7cffe1, 0x0b6f2112),
+ STCP(0x7f76892e, 0x0bb65336), STCP(0x7f6feab8, 0x0bfd81b3), STCP(0x7f692482, 0x0c44ac72),
+ STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5b20de, 0x0cd2f660), STCP(0x7f53e374, 0x0d1a1562),
+ STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f44f17c, 0x0da8470d), STCP(0x7f3d3cf3, 0x0def5989),
+ STCP(0x7f3560b8, 0x0e3667ad), STCP(0x7f2d5cd0, 0x0e7d7162), STCP(0x7f25313c, 0x0ec47692),
+ STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f14631c, 0x0f52730a), STCP(0x7f0bc096, 0x0f996a26),
+ STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efa04a7, 0x102749ae), STCP(0x7ef0eb45, 0x106e31ef),
+ STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ede41ba, 0x10fbf2fa), STCP(0x7ed4b197, 0x1142cb98),
+ STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec11aa4, 0x11d06c96), STCP(0x7eb713da, 0x121734cb),
+ STCP(0x7eace589, 0x125df75b), STCP(0x7ea28fb5, 0x12a4b431), STCP(0x7e981261, 0x12eb6b35),
+ STCP(0x7e8d6d90, 0x13321c53), STCP(0x7e82a145, 0x1378c774), STCP(0x7e77ad84, 0x13bf6c82),
+ STCP(0x7e6c9250, 0x14060b68), STCP(0x7e614fac, 0x144ca40e), STCP(0x7e55e59d, 0x1493365f),
+ STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e3e9b49, 0x152047ab), STCP(0x7e32bb0b, 0x1566c679),
+ STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e1a847b, 0x15f3aff8), STCP(0x7e0e2e31, 0x163a1a7e),
+ STCP(0x7e01b095, 0x16807e14), STCP(0x7df50baa, 0x16c6daa6), STCP(0x7de83f76, 0x170d301d),
+ STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dce313e, 0x1799c562), STCP(0x7dc0ef43, 0x17e00505),
+ STCP(0x7db3860e, 0x18263d35), STCP(0x7da5f5a4, 0x186c6ddd), STCP(0x7d983e08, 0x18b296e7),
+ STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7c594d, 0x193ed1c8), STCP(0x7d6e2c36, 0x1984e373),
+ STCP(0x7d5fd800, 0x19caed28), STCP(0x7d515cae, 0x1a10eed2), STCP(0x7d42ba45, 0x1a56e85b),
+ STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d25003f, 0x1ae2c2b0), STCP(0x7d15e8ac, 0x1b28a351),
+ STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cf7447e, 0x1bb44b13), STCP(0x7ce7b7ec, 0x1bfa1209),
+ STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cc829ea, 0x1c8585b0), STCP(0x7cb82884, 0x1ccb3237),
+ STCP(0x7ca80037, 0x1d10d5c1), STCP(0x7c97b108, 0x1d56703b), STCP(0x7c873afb, 0x1d9c018f),
+ STCP(0x7c769e17, 0x1de189a5), STCP(0x7c65da60, 0x1e27086a), STCP(0x7c54efdb, 0x1e6c7dc7),
+ STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c32a67d, 0x1ef74bf3), STCP(0x7c2147af, 0x1f3ca496),
+ STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bfe15f0, 0x1fc7388d), STCP(0x7bec430a, 0x200c73b4),
+ STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bc8294c, 0x2096cbf0), STCP(0x7bb5e27f, 0x20dbe8da),
+ STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b90e128, 0x216603d7), STCP(0x7b7e26a9, 0x21ab01c0),
+ STCP(0x7b6b45a4, 0x21eff528), STCP(0x7b583e20, 0x2234ddfa), STCP(0x7b451022, 0x2279bc21),
+ STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b1e40d3, 0x23035817), STCP(0x7b0a9f8d, 0x234815ba),
+ STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae2e9e3, 0x23d16fe8), STCP(0x7aced58b, 0x24160c47),
+ STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7aa639f7, 0x249f232b), STCP(0x7a91b2c6, 0x24e39d85),
+ STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6831b9, 0x256c6f9f), STCP(0x7a5337e9, 0x25b0c734),
+ STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a28d1d8, 0x26395303), STCP(0x7a1365a4, 0x267d8713),
+ STCP(0x79fdd35b, 0x26c1af21), STCP(0x79e81b05, 0x2705cb19), STCP(0x79d23ca9, 0x2749dae4),
+ STCP(0x79bc384c, 0x278dde6e), STCP(0x79a60df7, 0x27d1d5a2), STCP(0x798fbdaf, 0x2815c069),
+ STCP(0x7979477c, 0x28599eb0), STCP(0x7962ab66, 0x289d7061), STCP(0x794be972, 0x28e13566),
+ STCP(0x793501a8, 0x2924edab), STCP(0x791df40f, 0x2968991b), STCP(0x7906c0af, 0x29ac37a0),
+ STCP(0x78ef678e, 0x29efc925), STCP(0x78d7e8b5, 0x2a334d95), STCP(0x78c04429, 0x2a76c4dc),
+ STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78908a1a, 0x2afd8b97), STCP(0x787874a6, 0x2b40dae2),
+ STCP(0x7860399d, 0x2b841caf), STCP(0x7847d908, 0x2bc750e9), STCP(0x782f52ef, 0x2c0a777b),
+ STCP(0x7816a758, 0x2c4d9050), STCP(0x77fdd64b, 0x2c909b54), STCP(0x77e4dfd1, 0x2cd39870),
+ STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b282b3, 0x2d5968a2), STCP(0x77991c1e, 0x2d9c3b8e),
+ STCP(0x777f903b, 0x2ddf003f), STCP(0x7765df12, 0x2e21b6a2), STCP(0x774c08aa, 0x2e645ea0),
+ STCP(0x77320d0c, 0x2ea6f826), STCP(0x7717ec40, 0x2ee9831f), STCP(0x76fda64e, 0x2f2bff76),
+ STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76c8ab18, 0x2fb0cbea), STCP(0x76adf5e5, 0x2ff31bdd),
+ STCP(0x76931bae, 0x30355cdc), STCP(0x76781c79, 0x30778ed2), STCP(0x765cf850, 0x30b9b1a9),
+ STCP(0x7641af3c, 0x30fbc54d), STCP(0x76264144, 0x313dc9aa), STCP(0x760aae72, 0x317fbeaa),
+ STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75d31a60, 0x32037a45), STCP(0x75b71931, 0x324540b6),
+ STCP(0x759af34b, 0x3286f778), STCP(0x757ea8b5, 0x32c89e78), STCP(0x75623979, 0x330a35a1),
+ STCP(0x7545a59f, 0x334bbcde), STCP(0x7528ed31, 0x338d341a), STCP(0x750c1038, 0x33ce9b42),
+ STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d1e8c5, 0x34513903), STCP(0x74b49e5f, 0x34926f74),
+ STCP(0x74972f91, 0x34d3957e), STCP(0x74799c65, 0x3514ab0d), STCP(0x745be4e4, 0x3555b00e),
+ STCP(0x743e0917, 0x3596a46c), STCP(0x74200908, 0x35d78813), STCP(0x7401e4c0, 0x36185aee),
+ STCP(0x73e39c48, 0x36591cea), STCP(0x73c52faa, 0x3699cdf1), STCP(0x73a69ef0, 0x36da6df1),
+ STCP(0x7387ea22, 0x371afcd4), STCP(0x7369114b, 0x375b7a87), STCP(0x734a1474, 0x379be6f6),
+ STCP(0x732af3a6, 0x37dc420c), STCP(0x730baeec, 0x381c8bb5), STCP(0x72ec4650, 0x385cc3de),
+ STCP(0x72ccb9da, 0x389cea71), STCP(0x72ad0995, 0x38dcff5d), STCP(0x728d358b, 0x391d028b),
+ STCP(0x726d3dc5, 0x395cf3e9), STCP(0x724d224e, 0x399cd362), STCP(0x722ce330, 0x39dca0e2),
+ STCP(0x720c8074, 0x3a1c5c56), STCP(0x71ebfa25, 0x3a5c05aa), STCP(0x71cb504d, 0x3a9b9cc9),
+ STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7189922b, 0x3b1a941c), STCP(0x71687df5, 0x3b59f428),
+ STCP(0x7147465f, 0x3b9941b0), STCP(0x7125eb74, 0x3bd87ca1), STCP(0x71046d3d, 0x3c17a4e8),
+ STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c10717, 0x3c95bd25), STCP(0x709f1f3d, 0x3cd4acf5),
+ STCP(0x707d1442, 0x3d1389cb), STCP(0x705ae630, 0x3d525394), STCP(0x70389513, 0x3d910a3c),
+ STCP(0x701620f4, 0x3dcfadaf), STCP(0x6ff389de, 0x3e0e3ddb), STCP(0x6fd0cfdd, 0x3e4cbaac),
+ STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f8af343, 0x3ec979ed), STCP(0x6f67d0c0, 0x3f07bc37),
+ STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f212384, 0x3f8405bb), STCP(0x6efd98e2, 0x3fc20ccf),
+ STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6eb61bcb, 0x403ddf39), STCP(0x6e92296d, 0x407baa69),
+ STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e49dd44, 0x40f7045f), STCP(0x6e25838f, 0x413492fd),
+ STCP(0x6e01077f, 0x41720d45), STCP(0x6ddc691e, 0x41af7323), STCP(0x6db7a879, 0x41ecc483),
+ STCP(0x6d92c59a, 0x422a0154), STCP(0x6d6dc08e, 0x42672980), STCP(0x6d48995f, 0x42a43cf7),
+ STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cfde4c9, 0x431e2573), STCP(0x6cd85779, 0x435afa54),
+ STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c8cd70a, 0x43d464fa), STCP(0x6c66e403, 0x4410fa9a),
+ STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6c1a988f, 0x4489e615), STCP(0x6bf4403a, 0x44c63bca),
+ STCP(0x6bcdc639, 0x45027c0c), STCP(0x6ba72a97, 0x453ea6c7), STCP(0x6b806d61, 0x457abbe8),
+ STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b328e67, 0x45f2a513), STCP(0x6b0b6cbc, 0x462e78f8),
+ STCP(0x6ae429ad, 0x466a36f9), STCP(0x6abcc546, 0x46a5df02), STCP(0x6a953f94, 0x46e17102),
+ STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a45d080, 0x4758529c), STCP(0x6a1de736, 0x4793a210),
+ STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69cdb161, 0x4809fdeb), STCP(0x69a564ef, 0x48450a2d),
+ STCP(0x697cf789, 0x487fffe3), STCP(0x6954693b, 0x48badefd), STCP(0x692bba13, 0x48f5a767),
+ STCP(0x6902ea1c, 0x4930590e), STCP(0x68d9f964, 0x496af3e1), STCP(0x68b0e7f6, 0x49a577ce),
+ STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x685e6331, 0x4a1a3aaa), STCP(0x6834eff2, 0x4a547975),
+ STCP(0x680b5c33, 0x4a8ea111), STCP(0x67e1a7ff, 0x4ac8b16b), STCP(0x67b7d363, 0x4b02aa71),
+ STCP(0x678dde6e, 0x4b3c8c11), STCP(0x6763c92b, 0x4b76563a), STCP(0x673993a8, 0x4bb008d8),
+ STCP(0x670f3df2, 0x4be9a3db), STCP(0x66e4c817, 0x4c23272f), STCP(0x66ba3223, 0x4c5c92c4),
+ STCP(0x668f7c24, 0x4c95e687), STCP(0x6664a627, 0x4ccf2267), STCP(0x6639b03a, 0x4d084651),
+ STCP(0x660e9a69, 0x4d415233), STCP(0x65e364c3, 0x4d7a45fd), STCP(0x65b80f55, 0x4db3219c),
+ STCP(0x658c9a2d, 0x4debe4fe), STCP(0x65610557, 0x4e249011), STCP(0x653550e1, 0x4e5d22c5),
+ STCP(0x65097cda, 0x4e959d07), STCP(0x64dd894f, 0x4ecdfec6), STCP(0x64b1764d, 0x4f0647f0),
+ STCP(0x648543e3, 0x4f3e7874), STCP(0x6458f21d, 0x4f769040), STCP(0x642c810b, 0x4fae8f42),
+ STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63d34136, 0x501e42a5), STCP(0x63a6728f, 0x5055f6e2),
+ STCP(0x637984d4, 0x508d9211), STCP(0x634c7810, 0x50c5141e), STCP(0x631f4c54, 0x50fc7cfa),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62c49826, 0x516b02d8), STCP(0x62970fd2, 0x51a21fb7),
+ STCP(0x626968be, 0x51d92320), STCP(0x623ba2f6, 0x52100d01), STCP(0x620dbe8a, 0x5246dd48),
+ STCP(0x61dfbb89, 0x527d93e6), STCP(0x61b19a00, 0x52b430c8), STCP(0x618359fd, 0x52eab3de),
+ STCP(0x6154fb90, 0x53211d17), STCP(0x61267ec7, 0x53576c62), STCP(0x60f7e3b0, 0x538da1ae),
+ STCP(0x60c92a59, 0x53c3bce9), STCP(0x609a52d2, 0x53f9be04), STCP(0x606b5d28, 0x542fa4ed),
+ STCP(0x603c496c, 0x54657194), STCP(0x600d17aa, 0x549b23e7), STCP(0x5fddc7f3, 0x54d0bbd6),
+ STCP(0x5fae5a54, 0x55063950), STCP(0x5f7ecedd, 0x553b9c45), STCP(0x5f4f259c, 0x5570e4a3),
+ STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5eef79f8, 0x55db255b), STCP(0x5ebf77b4, 0x56101d94),
+ STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e5f1a90, 0x5679bd6b), STCP(0x5e2ebfcf, 0x56ae64e9),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dcdb239, 0x571762b6), STCP(0x5d9cff82, 0x574bb8e6),
+ STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d3b428b, 0x57b41383), STCP(0x5d0a3868, 0x57e817d1),
+ STCP(0x5cd91140, 0x581c00b3), STCP(0x5ca7cd21, 0x584fce19), STCP(0x5c766c1c, 0x58837ff3),
+ STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c13539a, 0x58ea90c3), STCP(0x5be19c3c, 0x591def98),
+ STCP(0x5bafc836, 0x595132a2), STCP(0x5b7dd796, 0x598459ce), STCP(0x5b4bca6c, 0x59b7650f),
+ STCP(0x5b19a0c7, 0x59ea5454), STCP(0x5ae75ab8, 0x5a1d278c), STCP(0x5ab4f84f, 0x5a4fdea9),
+ STCP(0x5a827999, 0x5a827999)
+};
+#endif
+const PWord32 SineTable960[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7ffff4c4, 0x00359dd2), STCP(0x7fffd314, 0x006b3b9b),
+ STCP(0x7fff9aee, 0x00a0d951), STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffee743, 0x010c1460),
+ STCP(0x7ffe6bbe, 0x0141b1a5), STCP(0x7ffdd9c3, 0x01774eb2), STCP(0x7ffd3153, 0x01aceb7c),
+ STCP(0x7ffc726e, 0x01e287fc), STCP(0x7ffb9d14, 0x02182427), STCP(0x7ffab146, 0x024dbff4),
+ STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff8964c, 0x02b8f64e), STCP(0x7ff76720, 0x02ee90c8),
+ STCP(0x7ff62181, 0x03242abf), STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff352e7, 0x038f5cfb),
+ STCP(0x7ff1c9ee, 0x03c4f52e), STCP(0x7ff02a81, 0x03fa8cb8), STCP(0x7fee74a1, 0x0430238f),
+ STCP(0x7feca850, 0x0465b9aa), STCP(0x7feac58c, 0x049b4f00), STCP(0x7fe8cc56, 0x04d0e386),
+ STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe49697, 0x053c0a01), STCP(0x7fe25a0e, 0x05719be2),
+ STCP(0x7fe00715, 0x05a72ccf), STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fdb1dd4, 0x06124ba5),
+ STCP(0x7fd8878d, 0x0647d97c), STCP(0x7fd5dad7, 0x067d6639), STCP(0x7fd317b3, 0x06b2f1d2),
+ STCP(0x7fd03e22, 0x06e87c3f), STCP(0x7fcd4e23, 0x071e0575), STCP(0x7fca47b8, 0x07538d6b),
+ STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc3f79f, 0x07be9973), STCP(0x7fc0adf1, 0x07f41d72),
+ STCP(0x7fbd4dd9, 0x0829a00b), STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb64a6d, 0x0894a0e9),
+ STCP(0x7fb2a71a, 0x08ca1f1b), STCP(0x7faeed5e, 0x08ff9bc2), STCP(0x7fab1d3c, 0x093516d4),
+ STCP(0x7fa736b3, 0x096a9049), STCP(0x7fa339c4, 0x09a00817), STCP(0x7f9f2670, 0x09d57e35),
+ STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f96bc9b, 0x0a40653a), STCP(0x7f92661c, 0x0a75d60e),
+ STCP(0x7f8df93b, 0x0aab450d), STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f84dc54, 0x0b161d63),
+ STCP(0x7f802c51, 0x0b4b86a8), STCP(0x7f7b65ee, 0x0b80edf1), STCP(0x7f76892e, 0x0bb65336),
+ STCP(0x7f719610, 0x0bebb66c), STCP(0x7f6c8c95, 0x0c21178c), STCP(0x7f676cbf, 0x0c56768a),
+ STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5cea04, 0x0cc12dff), STCP(0x7f578720, 0x0cf68662),
+ STCP(0x7f520de5, 0x0d2bdc80), STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f46d86b, 0x0d9681c2),
+ STCP(0x7f411c2e, 0x0dcbd0d5), STCP(0x7f3b499c, 0x0e011d7c), STCP(0x7f3560b8, 0x0e3667ad),
+ STCP(0x7f2f6182, 0x0e6baf61), STCP(0x7f294bfc, 0x0ea0f48c), STCP(0x7f232025, 0x0ed63727),
+ STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f16858d, 0x0f40b483), STCP(0x7f1016cd, 0x0f75ef32),
+ STCP(0x7f0991c3, 0x0fab272b), STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efc44cf, 0x10158ed4),
+ STCP(0x7ef57cea, 0x104abe71), STCP(0x7eee9ebd, 0x107feb33), STCP(0x7ee7aa4b, 0x10b5150f),
+ STCP(0x7ee09f94, 0x10ea3bfd), STCP(0x7ed97e9b, 0x111f5ff3), STCP(0x7ed24760, 0x115480e9),
+ STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec39629, 0x11beb9aa), STCP(0x7ebc1c30, 0x11f3d164),
+ STCP(0x7eb48bfa, 0x1228e5f7), STCP(0x7eace589, 0x125df75b), STCP(0x7ea528df, 0x12930586),
+ STCP(0x7e9d55fb, 0x12c8106e), STCP(0x7e956ce0, 0x12fd180b), STCP(0x7e8d6d90, 0x13321c53),
+ STCP(0x7e85580b, 0x13671d3d), STCP(0x7e7d2c53, 0x139c1abf), STCP(0x7e74ea69, 0x13d114d0),
+ STCP(0x7e6c9250, 0x14060b68), STCP(0x7e642407, 0x143afe7b), STCP(0x7e5b9f92, 0x146fee02),
+ STCP(0x7e5304f1, 0x14a4d9f3), STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e418d31, 0x150ea6ef),
+ STCP(0x7e38b016, 0x154387e6), STCP(0x7e2fbcd5, 0x15786522), STCP(0x7e26b370, 0x15ad3e9a),
+ STCP(0x7e1d93e9, 0x15e21444), STCP(0x7e145e41, 0x1616e618), STCP(0x7e0b1279, 0x164bb40b),
+ STCP(0x7e01b095, 0x16807e14), STCP(0x7df83894, 0x16b5442b), STCP(0x7deeaa79, 0x16ea0646),
+ STCP(0x7de50645, 0x171ec45c), STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dd17b9b, 0x17883452),
+ STCP(0x7dc79528, 0x17bce621), STCP(0x7dbd98a3, 0x17f193c5), STCP(0x7db3860e, 0x18263d35),
+ STCP(0x7da95d6b, 0x185ae269), STCP(0x7d9f1ebc, 0x188f8357), STCP(0x7d94ca02, 0x18c41ff6),
+ STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7fde75, 0x192d4c21), STCP(0x7d7547a6, 0x1961db9b),
+ STCP(0x7d6a9ad4, 0x199666a0), STCP(0x7d5fd800, 0x19caed28), STCP(0x7d54ff2d, 0x19ff6f2a),
+ STCP(0x7d4a105c, 0x1a33ec9c), STCP(0x7d3f0b8f, 0x1a686575), STCP(0x7d33f0c9, 0x1a9cd9ac),
+ STCP(0x7d28c00b, 0x1ad14938), STCP(0x7d1d7957, 0x1b05b40e), STCP(0x7d121caf, 0x1b3a1a27),
+ STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cfb218b, 0x1ba2d7fc), STCP(0x7cef8314, 0x1bd72fa4),
+ STCP(0x7ce3ceb1, 0x1c0b826a), STCP(0x7cd80464, 0x1c3fd045), STCP(0x7ccc242f, 0x1c74192a),
+ STCP(0x7cc02e14, 0x1ca85d12), STCP(0x7cb42216, 0x1cdc9bf2), STCP(0x7ca80037, 0x1d10d5c1),
+ STCP(0x7c9bc879, 0x1d450a78), STCP(0x7c8f7add, 0x1d793a0b), STCP(0x7c831766, 0x1dad6473),
+ STCP(0x7c769e17, 0x1de189a5), STCP(0x7c6a0ef1, 0x1e15a99a), STCP(0x7c5d69f6, 0x1e49c447),
+ STCP(0x7c50af2a, 0x1e7dd9a3), STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c36f823, 0x1ee5f447),
+ STCP(0x7c29fbed, 0x1f19f97b), STCP(0x7c1ce9ee, 0x1f4df93a), STCP(0x7c0fc229, 0x1f81f37b),
+ STCP(0x7c02849f, 0x1fb5e835), STCP(0x7bf53152, 0x1fe9d75f), STCP(0x7be7c846, 0x201dc0ef),
+ STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bccb4f7, 0x2085831e), STCP(0x7bbf0ab9, 0x20b95bac),
+ STCP(0x7bb14ac4, 0x20ed2e7b), STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b9589c2, 0x2154c2bb),
+ STCP(0x7b8788b9, 0x2188841a), STCP(0x7b797204, 0x21bc3f97), STCP(0x7b6b45a4, 0x21eff528),
+ STCP(0x7b5d039d, 0x2223a4c5), STCP(0x7b4eabf0, 0x22574e65), STCP(0x7b403ea1, 0x228af1fe),
+ STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b232324, 0x22f226f8), STCP(0x7b1474fc, 0x2325b847),
+ STCP(0x7b05b13c, 0x2359436c), STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae7e8fb, 0x23c04710),
+ STCP(0x7ad8e481, 0x23f3bf7e), STCP(0x7ac9ca79, 0x2427319d), STCP(0x7aba9ae5, 0x245a9d64),
+ STCP(0x7aab55c9, 0x248e02ca), STCP(0x7a9bfb26, 0x24c161c7), STCP(0x7a8c8b00, 0x24f4ba50),
+ STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6d6a36, 0x255b57e6), STCP(0x7a5db997, 0x258e9ce0),
+ STCP(0x7a4df37f, 0x25c1db43), STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a2e26f1, 0x26284421),
+ STCP(0x7a1e2081, 0x265b6e8a), STCP(0x7a0e04a3, 0x268e9238), STCP(0x79fdd35b, 0x26c1af21),
+ STCP(0x79ed8cac, 0x26f4c53e), STCP(0x79dd3097, 0x2727d485), STCP(0x79ccbf21, 0x275adcee),
+ STCP(0x79bc384c, 0x278dde6e), STCP(0x79ab9c1b, 0x27c0d8fe), STCP(0x799aea91, 0x27f3cc94),
+ STCP(0x798a23b0, 0x2826b928), STCP(0x7979477c, 0x28599eb0), STCP(0x796855f8, 0x288c7d24),
+ STCP(0x79574f27, 0x28bf547a), STCP(0x7946330b, 0x28f224aa), STCP(0x793501a8, 0x2924edab),
+ STCP(0x7923bb00, 0x2957af74), STCP(0x79125f18, 0x298a69fc), STCP(0x7900edf1, 0x29bd1d3a),
+ STCP(0x78ef678e, 0x29efc925), STCP(0x78ddcbf4, 0x2a226db4), STCP(0x78cc1b25, 0x2a550adf),
+ STCP(0x78ba5523, 0x2a87a09c), STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78968997, 0x2aecb5ab),
+ STCP(0x78848413, 0x2b1f34eb), STCP(0x78726969, 0x2b51ac9a), STCP(0x7860399d, 0x2b841caf),
+ STCP(0x784df4b2, 0x2bb68521), STCP(0x783b9aac, 0x2be8e5e8), STCP(0x78292b8c, 0x2c1b3efb),
+ STCP(0x7816a758, 0x2c4d9050), STCP(0x78040e11, 0x2c7fd9df), STCP(0x77f15fbb, 0x2cb21ba0),
+ STCP(0x77de9c5a, 0x2ce45589), STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b8d683, 0x2d48b1b1),
+ STCP(0x77a5d413, 0x2d7ad3de), STCP(0x7792bca4, 0x2dacee10), STCP(0x777f903b, 0x2ddf003f),
+ STCP(0x776c4eda, 0x2e110a62), STCP(0x7758f885, 0x2e430c6f), STCP(0x77458d3f, 0x2e75065e),
+ STCP(0x77320d0c, 0x2ea6f826), STCP(0x771e77ef, 0x2ed8e1bf), STCP(0x770acdeb, 0x2f0ac320),
+ STCP(0x76f70f04, 0x2f3c9c3f), STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76cf529b, 0x2fa03599),
+ STCP(0x76bb5520, 0x2fd1f5c1), STCP(0x76a742d0, 0x3003ad85), STCP(0x76931bae, 0x30355cdc),
+ STCP(0x767edfbd, 0x306703be), STCP(0x766a8f03, 0x3098a222), STCP(0x76562981, 0x30ca37ff),
+ STCP(0x7641af3c, 0x30fbc54d), STCP(0x762d2037, 0x312d4a02), STCP(0x76187c76, 0x315ec617),
+ STCP(0x7603c3fc, 0x31903982), STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75da14ee, 0x31f30638),
+ STCP(0x75c51e60, 0x32245f72), STCP(0x75b01329, 0x3255afe0), STCP(0x759af34b, 0x3286f778),
+ STCP(0x7585beca, 0x32b83634), STCP(0x757075ab, 0x32e96c09), STCP(0x755b17f1, 0x331a98ef),
+ STCP(0x7545a59f, 0x334bbcde), STCP(0x75301eba, 0x337cd7cc), STCP(0x751a8345, 0x33ade9b2),
+ STCP(0x7504d344, 0x33def287), STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d935ad, 0x3440e8da),
+ STCP(0x74c3481f, 0x3471d647), STCP(0x74ad4614, 0x34a2ba80), STCP(0x74972f91, 0x34d3957e),
+ STCP(0x74810498, 0x35046736), STCP(0x746ac52e, 0x35352fa1), STCP(0x74547157, 0x3565eeb6),
+ STCP(0x743e0917, 0x3596a46c), STCP(0x74278c71, 0x35c750bb), STCP(0x7410fb6a, 0x35f7f39b),
+ STCP(0x73fa5606, 0x36288d03), STCP(0x73e39c48, 0x36591cea), STCP(0x73ccce35, 0x3689a347),
+ STCP(0x73b5ebd0, 0x36ba2013), STCP(0x739ef51e, 0x36ea9345), STCP(0x7387ea22, 0x371afcd4),
+ STCP(0x7370cae1, 0x374b5cb8), STCP(0x7359975f, 0x377bb2e8), STCP(0x73424f9f, 0x37abff5c),
+ STCP(0x732af3a6, 0x37dc420c), STCP(0x73138379, 0x380c7aee), STCP(0x72fbff1a, 0x383ca9fb),
+ STCP(0x72e4668e, 0x386ccf29), STCP(0x72ccb9da, 0x389cea71), STCP(0x72b4f901, 0x38ccfbcb),
+ STCP(0x729d2408, 0x38fd032d), STCP(0x72853af2, 0x392d008f), STCP(0x726d3dc5, 0x395cf3e9),
+ STCP(0x72552c84, 0x398cdd32), STCP(0x723d0733, 0x39bcbc62), STCP(0x7224cdd7, 0x39ec9171),
+ STCP(0x720c8074, 0x3a1c5c56), STCP(0x71f41f0e, 0x3a4c1d09), STCP(0x71dba9aa, 0x3a7bd381),
+ STCP(0x71c3204b, 0x3aab7fb6), STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7191d1b0, 0x3b0ab937),
+ STCP(0x71790c7d, 0x3b3a4671), STCP(0x71603360, 0x3b69c947), STCP(0x7147465f, 0x3b9941b0),
+ STCP(0x712e457e, 0x3bc8afa4), STCP(0x711530c1, 0x3bf8131b), STCP(0x70fc082d, 0x3c276c0c),
+ STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c97b8f, 0x3c85fe3c), STCP(0x70b0178f, 0x3cb5376b),
+ STCP(0x70969fc9, 0x3ce465f2), STCP(0x707d1442, 0x3d1389cb), STCP(0x706374fe, 0x3d42a2ec),
+ STCP(0x7049c202, 0x3d71b14d), STCP(0x702ffb53, 0x3da0b4e6), STCP(0x701620f4, 0x3dcfadaf),
+ STCP(0x6ffc32ea, 0x3dfe9ba0), STCP(0x6fe2313b, 0x3e2d7eb0), STCP(0x6fc81be9, 0x3e5c56d8),
+ STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f93b675, 0x3eb9e64b), STCP(0x6f79665a, 0x3ee89d86),
+ STCP(0x6f5f02b1, 0x3f1749b7), STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f2a00c3, 0x3f7480dd),
+ STCP(0x6f0f6288, 0x3fa30bc0), STCP(0x6ef4b0d0, 0x3fd18b79), STCP(0x6ed9eba1, 0x3fffffff),
+ STCP(0x6ebf12fe, 0x402e694b), STCP(0x6ea426ed, 0x405cc754), STCP(0x6e892772, 0x408b1a12),
+ STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e52ee51, 0x40e79d8c), STCP(0x6e37b4b6, 0x4115ce38),
+ STCP(0x6e1c67c3, 0x4143f378), STCP(0x6e01077f, 0x41720d45), STCP(0x6de593ed, 0x41a01b96),
+ STCP(0x6dca0d14, 0x41ce1e64), STCP(0x6dae72f6, 0x41fc15a6), STCP(0x6d92c59a, 0x422a0154),
+ STCP(0x6d770505, 0x4257e166), STCP(0x6d5b313a, 0x4285b5d4), STCP(0x6d3f4a3f, 0x42b37e95),
+ STCP(0x6d23501a, 0x42e13ba3), STCP(0x6d0742ce, 0x430eecf5), STCP(0x6ceb2260, 0x433c9283),
+ STCP(0x6cceeed7, 0x436a2c44), STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c964e82, 0x43c53c43),
+ STCP(0x6c79e1c1, 0x43f2b270), STCP(0x6c5d61f8, 0x44201cb2), STCP(0x6c40cf2b, 0x444d7aff),
+ STCP(0x6c24295f, 0x447acd50), STCP(0x6c07709b, 0x44a8139d), STCP(0x6beaa4e1, 0x44d54dde),
+ STCP(0x6bcdc639, 0x45027c0c), STCP(0x6bb0d4a6, 0x452f9e1e), STCP(0x6b93d02d, 0x455cb40c),
+ STCP(0x6b76b8d5, 0x4589bdce), STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b3c5199, 0x45e3acb1),
+ STCP(0x6b1f01bf, 0x461091c1), STCP(0x6b019f19, 0x463d6a86), STCP(0x6ae429ad, 0x466a36f9),
+ STCP(0x6ac6a180, 0x4696f710), STCP(0x6aa90696, 0x46c3aac5), STCP(0x6a8b58f6, 0x46f0520f),
+ STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a4fc5a5, 0x47497b44), STCP(0x6a31dfff, 0x4775fd1f),
+ STCP(0x6a13e7b7, 0x47a27270), STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69d7bf56, 0x47fb3757),
+ STCP(0x69b98f47, 0x482786dc), STCP(0x699b4cac, 0x4853c9b8), STCP(0x697cf789, 0x487fffe3),
+ STCP(0x695e8fe4, 0x48ac2956), STCP(0x694015c2, 0x48d84609), STCP(0x69218928, 0x490455f3),
+ STCP(0x6902ea1c, 0x4930590e), STCP(0x68e438a3, 0x495c4f51), STCP(0x68c574c3, 0x498838b6),
+ STCP(0x68a69e80, 0x49b41533), STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6868baeb, 0x4a0ba75a),
+ STCP(0x6849ada3, 0x4a375cf4), STCP(0x682a8e0e, 0x4a630589), STCP(0x680b5c33, 0x4a8ea111),
+ STCP(0x67ec1816, 0x4aba2f83), STCP(0x67ccc1bd, 0x4ae5b0d9), STCP(0x67ad592e, 0x4b11250b),
+ STCP(0x678dde6e, 0x4b3c8c11), STCP(0x676e5182, 0x4b67e5e4), STCP(0x674eb270, 0x4b93327b),
+ STCP(0x672f013f, 0x4bbe71d0), STCP(0x670f3df2, 0x4be9a3db), STCP(0x66ef6890, 0x4c14c894),
+ STCP(0x66cf811f, 0x4c3fdff3), STCP(0x66af87a4, 0x4c6ae9f1), STCP(0x668f7c24, 0x4c95e687),
+ STCP(0x666f5ea5, 0x4cc0d5ad), STCP(0x664f2f2e, 0x4cebb75c), STCP(0x662eedc2, 0x4d168b8b),
+ STCP(0x660e9a69, 0x4d415233), STCP(0x65ee3528, 0x4d6c0b4e), STCP(0x65cdbe05, 0x4d96b6d3),
+ STCP(0x65ad3504, 0x4dc154bb), STCP(0x658c9a2d, 0x4debe4fe), STCP(0x656bed84, 0x4e166795),
+ STCP(0x654b2f0f, 0x4e40dc78), STCP(0x652a5ed5, 0x4e6b43a1), STCP(0x65097cda, 0x4e959d07),
+ STCP(0x64e88925, 0x4ebfe8a4), STCP(0x64c783bc, 0x4eea266f), STCP(0x64a66ca4, 0x4f145662),
+ STCP(0x648543e3, 0x4f3e7874), STCP(0x6464097e, 0x4f688c9f), STCP(0x6442bd7d, 0x4f9292db),
+ STCP(0x64215fe4, 0x4fbc8b21), STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63de7003, 0x501051ad),
+ STCP(0x63bcddc6, 0x503a1fe4), STCP(0x639b3a0a, 0x5063e008), STCP(0x637984d4, 0x508d9211),
+ STCP(0x6357be29, 0x50b735f7), STCP(0x6335e610, 0x50e0cbb4), STCP(0x6313fc8f, 0x510a5340),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62cff56c, 0x515d37a8), STCP(0x62add7d5, 0x51869476),
+ STCP(0x628ba8ef, 0x51afe2f5), STCP(0x626968be, 0x51d92320), STCP(0x62471748, 0x520254ee),
+ STCP(0x6224b494, 0x522b7859), STCP(0x620240a8, 0x52548d58), STCP(0x61dfbb89, 0x527d93e6),
+ STCP(0x61bd253e, 0x52a68bfa), STCP(0x619a7dcd, 0x52cf758e), STCP(0x6177c53c, 0x52f8509a),
+ STCP(0x6154fb90, 0x53211d17), STCP(0x613220d1, 0x5349daff), STCP(0x610f3504, 0x53728a49),
+ STCP(0x60ec382f, 0x539b2aef), STCP(0x60c92a59, 0x53c3bce9), STCP(0x60a60b87, 0x53ec4032),
+ STCP(0x6082dbc0, 0x5414b4c0), STCP(0x605f9b0b, 0x543d1a8e), STCP(0x603c496c, 0x54657194),
+ STCP(0x6018e6ea, 0x548db9cb), STCP(0x5ff5738c, 0x54b5f32c), STCP(0x5fd1ef58, 0x54de1db0),
+ STCP(0x5fae5a54, 0x55063950), STCP(0x5f8ab486, 0x552e4605), STCP(0x5f66fdf4, 0x555643c8),
+ STCP(0x5f4336a6, 0x557e3291), STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5efb75ea, 0x55cde31d),
+ STCP(0x5ed77c89, 0x55f5a4d2), STCP(0x5eb37284, 0x561d5771), STCP(0x5e8f57e2, 0x5644faf4),
+ STCP(0x5e6b2ca8, 0x566c8f54), STCP(0x5e46f0dc, 0x5694148a), STCP(0x5e22a487, 0x56bb8a8f),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dd9da55, 0x570a48eb), STCP(0x5db55c85, 0x57319134),
+ STCP(0x5d90ce44, 0x5758ca31), STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d478089, 0x57a70e29),
+ STCP(0x5d22c11b, 0x57ce1916), STCP(0x5cfdf156, 0x57f5149c), STCP(0x5cd91140, 0x581c00b3),
+ STCP(0x5cb420df, 0x5842dd54), STCP(0x5c8f203a, 0x5869aa78), STCP(0x5c6a0f58, 0x5890681a),
+ STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c1fbcf5, 0x58ddb4b7), STCP(0x5bfa7b81, 0x590443a6),
+ STCP(0x5bd529ea, 0x592ac2f6), STCP(0x5bafc836, 0x595132a2), STCP(0x5b8a566b, 0x597792a1),
+ STCP(0x5b64d491, 0x599de2ed), STCP(0x5b3f42ae, 0x59c42380), STCP(0x5b19a0c7, 0x59ea5454),
+ STCP(0x5af3eee5, 0x5a107560), STCP(0x5ace2d0e, 0x5a36869f), STCP(0x5aa85b48, 0x5a5c8809),
+ STCP(0x5a827999, 0x5a827999),
+};
+# endif
+
+/*
+ Sine windows
+ */
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow20[10] = {
+# else
+const PWord16 SineWindow20[10] = {
+# endif
+ WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7d8a5f3f, 0x18f8b83c),
+ WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x743e0917, 0x3596a46c),
+ WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x648543e3, 0x4f3e7874),
+ WTCP(0x5dfe47ad, 0x56e2f15d),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow40[20] = {
+# else
+const PWord16 SineWindow40[20] = {
+# endif
+ WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7f62368f, 0x0c8bd35e),
+ WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7d06aa16, 0x1b6e7b7a),
+ WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x78ef678f, 0x29efc925),
+ WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x732af3a7, 0x37dc420c),
+ WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6bcdc639, 0x45027c0c),
+ WTCP(0x6902ea1d, 0x4930590f), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x62f201ac, 0x5133cc94),
+ WTCP(0x5fae5a55, 0x55063951), WTCP(0x5c44ee40, 0x58b71632),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow60[30] = {
+# else
+const PWord16 SineWindow60[30] = {
+# endif
+ WTCP(0x7ffd3153, 0x1aceb7c), WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7fb9d758, 0x85f2136),
+ WTCP(0x7f76892e, 0xbb65336), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7eace589, 0x125df75b),
+ WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7cd80464, 0x1c3fd045),
+ WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7a3e17f1, 0x25f51307),
+ WTCP(0x793501a8, 0x2924edab), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x76e33b3e, 0x2f6e6d15),
+ WTCP(0x759af34b, 0x3286f778), WTCP(0x743e0917, 0x3596a46c), WTCP(0x72ccb9da, 0x389cea71),
+ WTCP(0x7147465f, 0x3b9941b0), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6e01077f, 0x41720d45),
+ WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x6887b5e1, 0x49dfe4c2),
+ WTCP(0x668f7c24, 0x4c95e687), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x626968be, 0x51d92320),
+ WTCP(0x603c496c, 0x54657194), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5bafc836, 0x595132a2),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow80[40] = {
+# else
+const PWord16 SineWindow80[40] = {
+# endif
+ WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7fd8878e, 0x0647d97c),
+ WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f411c2f, 0x0dcbd0d5),
+ WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e38b017, 0x154387e6),
+ WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7cc02e15, 0x1ca85d12),
+ WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7ad8e482, 0x23f3bf7e),
+ WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79574f28, 0x28bf547b), WTCP(0x78848414, 0x2b1f34eb),
+ WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x75c51e61, 0x32245f72),
+ WTCP(0x74c34820, 0x3471d647), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x729d2409, 0x38fd032d),
+ WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6f0f6289, 0x3fa30bc1),
+ WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6b1f01c0, 0x461091c2),
+ WTCP(0x69b98f48, 0x482786dc), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x66cf8120, 0x4c3fdff4),
+ WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6224b495, 0x522b7859),
+ WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5d22c11c, 0x57ce1917),
+ WTCP(0x5b64d492, 0x599de2ee),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow120[60] = {
+# else
+const PWord16 SineWindow120[60] = {
+# endif
+ WTCP(0x7fff4c54, 0x00d676eb), WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fee74a2, 0x0430238f),
+ WTCP(0x7fdd9dad, 0x05dcbcbe), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fab1d3d, 0x093516d4),
+ WTCP(0x7f8975f9, 0x0ae0b22c), WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7f3560b9, 0x0e3667ad),
+ WTCP(0x7f02f66f, 0x0fe05c64), WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e8d6d91, 0x13321c53),
+ WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7db3860f, 0x18263d36),
+ WTCP(0x7d5fd801, 0x19caed29), WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7ca80038, 0x1d10d5c2),
+ WTCP(0x7c43de8e, 0x1eb1e9a7), WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7b6b45a5, 0x21eff528),
+ WTCP(0x7af6d7e6, 0x238cc85d), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x79fdd35c, 0x26c1af22),
+ WTCP(0x7979477d, 0x28599eb0), WTCP(0x78ef678f, 0x29efc925), WTCP(0x7860399e, 0x2b841caf),
+ WTCP(0x77cbc3f2, 0x2d168792), WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76931bae, 0x30355cdd),
+ WTCP(0x75eef6ce, 0x31c1a43b), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x74972f92, 0x34d3957e),
+ WTCP(0x73e39c49, 0x36591cea), WTCP(0x732af3a7, 0x37dc420c), WTCP(0x726d3dc6, 0x395cf3e9),
+ WTCP(0x71aa82f7, 0x3adb21a1), WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x701620f5, 0x3dcfadb0),
+ WTCP(0x6f448b7e, 0x3f45ead8), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6d92c59b, 0x422a0154),
+ WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6ae429ae, 0x466a36f9),
+ WTCP(0x69f5dcd3, 0x47cedb31), WTCP(0x6902ea1d, 0x4930590f), WTCP(0x680b5c33, 0x4a8ea111),
+ WTCP(0x670f3df3, 0x4be9a3db), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x65097cdb, 0x4e959d08),
+ WTCP(0x63fff0ba, 0x4fe6756a), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x61dfbb8a, 0x527d93e6),
+ WTCP(0x60c92a5a, 0x53c3bcea), WTCP(0x5fae5a55, 0x55063951), WTCP(0x5e8f57e2, 0x5644faf4),
+ WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5b19a0c8, 0x59ea5454),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow160[80] = {
+# else
+const PWord16 SineWindow160[80] = {
+# endif
+ WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ff62182, 0x03242abf),
+ WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fd03e23, 0x06e87c3f),
+ WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f8df93c, 0x0aab450d),
+ WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f2f6183, 0x0e6baf61),
+ WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7eb48bfb, 0x1228e5f8),
+ WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e1d93ea, 0x15e21445),
+ WTCP(0x7de50646, 0x171ec45c), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d6a9ad5, 0x199666a0),
+ WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c9bc87a, 0x1d450a78),
+ WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7bb14ac5, 0x20ed2e7b),
+ WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7aab55ca, 0x248e02cb),
+ WTCP(0x7a4df380, 0x25c1db44), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x798a23b1, 0x2826b928),
+ WTCP(0x7923bb01, 0x2957af74), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x784df4b3, 0x2bb68522),
+ WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76f70f05, 0x2f3c9c40),
+ WTCP(0x767edfbe, 0x306703bf), WTCP(0x7603c3fd, 0x31903982), WTCP(0x7585becb, 0x32b83634),
+ WTCP(0x7504d345, 0x33def287), WTCP(0x74810499, 0x35046736), WTCP(0x73fa5607, 0x36288d03),
+ WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72552c85, 0x398cdd32),
+ WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70969fca, 0x3ce465f3),
+ WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6ebf12ff, 0x402e694c),
+ WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6d770506, 0x4257e166), WTCP(0x6cceeed8, 0x436a2c45),
+ WTCP(0x6c242960, 0x447acd50), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6ac6a180, 0x4696f710),
+ WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x68a69e81, 0x49b41533),
+ WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x666f5ea6, 0x4cc0d5ae),
+ WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64215fe5, 0x4fbc8b22),
+ WTCP(0x6357be2a, 0x50b735f8), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x61bd253f, 0x52a68bfb),
+ WTCP(0x60ec3830, 0x539b2af0), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5f4336a7, 0x557e3292),
+ WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5cb420e0, 0x5842dd54),
+ WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5af3eee6, 0x5a107561),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow180[90] = {
+# else
+const PWord16 SineWindow180[90] = {
+# endif
+ WTCP(0x7fffb025, 0x008efa17), WTCP(0x7ffd3153, 0x01aceb7c), WTCP(0x7ff833bc, 0x02cad485),
+ WTCP(0x7ff0b779, 0x03e8af9e), WTCP(0x7fe6bcaf, 0x05067734), WTCP(0x7fda4390, 0x062425b6),
+ WTCP(0x7fcb4c5a, 0x0741b592), WTCP(0x7fb9d758, 0x085f2136), WTCP(0x7fa5e4e0, 0x097c6313),
+ WTCP(0x7f8f7558, 0x0a997597), WTCP(0x7f76892e, 0x0bb65336), WTCP(0x7f5b20de, 0x0cd2f660),
+ WTCP(0x7f3d3cf3, 0x0def5989), WTCP(0x7f1cde00, 0x0f0b7727), WTCP(0x7efa04a7, 0x102749ae),
+ WTCP(0x7ed4b197, 0x1142cb98), WTCP(0x7eace589, 0x125df75b), WTCP(0x7e82a145, 0x1378c774),
+ WTCP(0x7e55e59d, 0x1493365f), WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7df50baa, 0x16c6daa6),
+ WTCP(0x7dc0ef43, 0x17e00505), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7d515cae, 0x1a10eed2),
+ WTCP(0x7d15e8ac, 0x1b28a351), WTCP(0x7cd80464, 0x1c3fd045), WTCP(0x7c97b108, 0x1d56703b),
+ WTCP(0x7c54efdb, 0x1e6c7dc7), WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7bc8294c, 0x2096cbf0),
+ WTCP(0x7b7e26a9, 0x21ab01c0), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7ae2e9e3, 0x23d16fe8),
+ WTCP(0x7a91b2c6, 0x24e39d85), WTCP(0x7a3e17f1, 0x25f51307), WTCP(0x79e81b05, 0x2705cb19),
+ WTCP(0x798fbdaf, 0x2815c069), WTCP(0x793501a8, 0x2924edab), WTCP(0x78d7e8b5, 0x2a334d95),
+ WTCP(0x787874a6, 0x2b40dae2), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x77b282b3, 0x2d5968a2),
+ WTCP(0x774c08aa, 0x2e645ea0), WTCP(0x76e33b3e, 0x2f6e6d15), WTCP(0x76781c79, 0x30778ed2),
+ WTCP(0x760aae72, 0x317fbeaa), WTCP(0x759af34b, 0x3286f778), WTCP(0x7528ed31, 0x338d341a),
+ WTCP(0x74b49e5f, 0x34926f74), WTCP(0x743e0917, 0x3596a46c), WTCP(0x73c52faa, 0x3699cdf1),
+ WTCP(0x734a1474, 0x379be6f6), WTCP(0x72ccb9da, 0x389cea71), WTCP(0x724d224e, 0x399cd362),
+ WTCP(0x71cb504d, 0x3a9b9cc9), WTCP(0x7147465f, 0x3b9941b0), WTCP(0x70c10717, 0x3c95bd25),
+ WTCP(0x70389513, 0x3d910a3c), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6f212384, 0x3f8405bb),
+ WTCP(0x6e92296d, 0x407baa69), WTCP(0x6e01077f, 0x41720d45), WTCP(0x6d6dc08e, 0x42672980),
+ WTCP(0x6cd85779, 0x435afa54), WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6ba72a97, 0x453ea6c7),
+ WTCP(0x6b0b6cbc, 0x462e78f8), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x69cdb161, 0x4809fdeb),
+ WTCP(0x692bba13, 0x48f5a767), WTCP(0x6887b5e1, 0x49dfe4c2), WTCP(0x67e1a7ff, 0x4ac8b16b),
+ WTCP(0x673993a8, 0x4bb008d8), WTCP(0x668f7c24, 0x4c95e687), WTCP(0x65e364c3, 0x4d7a45fd),
+ WTCP(0x653550e1, 0x4e5d22c5), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x63d34136, 0x501e42a5),
+ WTCP(0x631f4c54, 0x50fc7cfa), WTCP(0x626968be, 0x51d92320), WTCP(0x61b19a00, 0x52b430c8),
+ WTCP(0x60f7e3b0, 0x538da1ae), WTCP(0x603c496c, 0x54657194), WTCP(0x5f7ecedd, 0x553b9c45),
+ WTCP(0x5ebf77b4, 0x56101d94), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5d3b428b, 0x57b41383),
+ WTCP(0x5c766c1c, 0x58837ff3), WTCP(0x5bafc836, 0x595132a2), WTCP(0x5ae75ab8, 0x5a1d278c),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow240[120] = {
+# else
+const PWord16 SineWindow240[120] = {
+# endif
+ WTCP(0x7fffd315, 0x006b3b9b), WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ffb9d15, 0x02182427),
+ WTCP(0x7ff76721, 0x02ee90c8), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7feac58d, 0x049b4f00),
+ WTCP(0x7fe25a0f, 0x05719be2), WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7fcd4e24, 0x071e0575),
+ WTCP(0x7fc0adf2, 0x07f41d72), WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7fa339c5, 0x09a00817),
+ WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f6c8c96, 0x0c21178c),
+ WTCP(0x7f578721, 0x0cf68662), WTCP(0x7f411c2f, 0x0dcbd0d5), WTCP(0x7f294bfd, 0x0ea0f48c),
+ WTCP(0x7f1016ce, 0x0f75ef33), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7ed97e9c, 0x111f5ff4),
+ WTCP(0x7ebc1c31, 0x11f3d164), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e7d2c54, 0x139c1abf),
+ WTCP(0x7e5b9f93, 0x146fee03), WTCP(0x7e38b017, 0x154387e6), WTCP(0x7e145e42, 0x1616e618),
+ WTCP(0x7deeaa7a, 0x16ea0646), WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d9f1ebd, 0x188f8357),
+ WTCP(0x7d7547a7, 0x1961db9b), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7d1d7958, 0x1b05b40f),
+ WTCP(0x7cef8315, 0x1bd72fa4), WTCP(0x7cc02e15, 0x1ca85d12), WTCP(0x7c8f7ade, 0x1d793a0b),
+ WTCP(0x7c5d69f7, 0x1e49c447), WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7bf53153, 0x1fe9d75f),
+ WTCP(0x7bbf0aba, 0x20b95bac), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7b4eabf1, 0x22574e65),
+ WTCP(0x7b1474fd, 0x2325b847), WTCP(0x7ad8e482, 0x23f3bf7e), WTCP(0x7a9bfb27, 0x24c161c7),
+ WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79dd3098, 0x2727d486),
+ WTCP(0x799aea92, 0x27f3cc94), WTCP(0x79574f28, 0x28bf547b), WTCP(0x79125f19, 0x298a69fc),
+ WTCP(0x78cc1b26, 0x2a550adf), WTCP(0x78848414, 0x2b1f34eb), WTCP(0x783b9aad, 0x2be8e5e8),
+ WTCP(0x77f15fbc, 0x2cb21ba0), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x7758f886, 0x2e430c6f),
+ WTCP(0x770acdec, 0x2f0ac320), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x766a8f04, 0x3098a223),
+ WTCP(0x76187c77, 0x315ec617), WTCP(0x75c51e61, 0x32245f72), WTCP(0x757075ac, 0x32e96c09),
+ WTCP(0x751a8346, 0x33ade9b3), WTCP(0x74c34820, 0x3471d647), WTCP(0x746ac52f, 0x35352fa1),
+ WTCP(0x7410fb6b, 0x35f7f39c), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x73599760, 0x377bb2e9),
+ WTCP(0x72fbff1b, 0x383ca9fb), WTCP(0x729d2409, 0x38fd032d), WTCP(0x723d0734, 0x39bcbc63),
+ WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x711530c2, 0x3bf8131c),
+ WTCP(0x70b01790, 0x3cb5376b), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6fe2313c, 0x3e2d7eb1),
+ WTCP(0x6f79665b, 0x3ee89d86), WTCP(0x6f0f6289, 0x3fa30bc1), WTCP(0x6ea426ed, 0x405cc754),
+ WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6d5b313b, 0x4285b5d4),
+ WTCP(0x6ceb2261, 0x433c9283), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6c07709b, 0x44a8139e),
+ WTCP(0x6b93d02e, 0x455cb40c), WTCP(0x6b1f01c0, 0x461091c2), WTCP(0x6aa90697, 0x46c3aac5),
+ WTCP(0x6a31e000, 0x4775fd1f), WTCP(0x69b98f48, 0x482786dc), WTCP(0x694015c3, 0x48d84609),
+ WTCP(0x68c574c4, 0x498838b6), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x67ccc1be, 0x4ae5b0da),
+ WTCP(0x674eb271, 0x4b93327c), WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x664f2f2e, 0x4cebb75c),
+ WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x64c783bd, 0x4eea2670),
+ WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6335e611, 0x50e0cbb4),
+ WTCP(0x62add7d6, 0x51869476), WTCP(0x6224b495, 0x522b7859), WTCP(0x619a7dce, 0x52cf758f),
+ WTCP(0x610f3505, 0x53728a4a), WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ff5738d, 0x54b5f32c),
+ WTCP(0x5f66fdf5, 0x555643c8), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5e46f0dd, 0x5694148b),
+ WTCP(0x5db55c86, 0x57319135), WTCP(0x5d22c11c, 0x57ce1917), WTCP(0x5c8f203b, 0x5869aa79),
+ WTCP(0x5bfa7b82, 0x590443a7), WTCP(0x5b64d492, 0x599de2ee), WTCP(0x5ace2d0f, 0x5a36869f),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow320[160] = {
+# else
+const PWord16 SineWindow320[160] = {
+# endif
+ WTCP(0x7fffe6bc, 0x00506cb9), WTCP(0x7fff1c9b, 0x00f145ab), WTCP(0x7ffd885a, 0x01921d20),
+ WTCP(0x7ffb29fd, 0x0232f21a), WTCP(0x7ff80186, 0x02d3c39b), WTCP(0x7ff40efa, 0x037490a5),
+ WTCP(0x7fef5260, 0x0415583b), WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fe37b22, 0x0556d30f),
+ WTCP(0x7fdc608f, 0x05f78453), WTCP(0x7fd47c14, 0x06982c2b), WTCP(0x7fcbcdbc, 0x0738c998),
+ WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7fb813b0, 0x0879e140), WTCP(0x7fad081b, 0x091a597e),
+ WTCP(0x7fa132e8, 0x09bac35d), WTCP(0x7f949429, 0x0a5b1dde), WTCP(0x7f872bf3, 0x0afb6805),
+ WTCP(0x7f78fa5b, 0x0b9ba0d5), WTCP(0x7f69ff76, 0x0c3bc74f), WTCP(0x7f5a3b5e, 0x0cdbda79),
+ WTCP(0x7f49ae2a, 0x0d7bd954), WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7f2638db, 0x0ebb962c),
+ WTCP(0x7f1350f8, 0x0f5b5231), WTCP(0x7effa069, 0x0ffaf5f6), WTCP(0x7eeb274d, 0x109a807e),
+ WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7ebfdbf5, 0x11d945eb), WTCP(0x7ea909fc, 0x12787ed8),
+ WTCP(0x7e917000, 0x13179a9b), WTCP(0x7e790e25, 0x13b69836), WTCP(0x7e5fe493, 0x145576b1),
+ WTCP(0x7e45f371, 0x14f43510), WTCP(0x7e2b3ae8, 0x1592d257), WTCP(0x7e0fbb22, 0x16314d8e),
+ WTCP(0x7df3744b, 0x16cfa5b9), WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7db8921c, 0x180be904),
+ WTCP(0x7d99f721, 0x18a9d231), WTCP(0x7d7a95cf, 0x1947946c), WTCP(0x7d5a6e57, 0x19e52ebb),
+ WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7d17cdc2, 0x1b1fe7b3), WTCP(0x7cf5550e, 0x1bbd046c),
+ WTCP(0x7cd21707, 0x1c59f557), WTCP(0x7cae13e4, 0x1cf6b97c), WTCP(0x7c894bde, 0x1d934fe5),
+ WTCP(0x7c63bf2f, 0x1e2fb79a), WTCP(0x7c3d6e13, 0x1ecbefa4), WTCP(0x7c1658c5, 0x1f67f70b),
+ WTCP(0x7bee7f85, 0x2003ccdb), WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7b9c8226, 0x213adfda),
+ WTCP(0x7b725e8a, 0x21d61b1e), WTCP(0x7b4777fe, 0x227120f3), WTCP(0x7b1bcec4, 0x230bf065),
+ WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7ac23561, 0x2440e84d), WTCP(0x7a9445c5, 0x24db0edb),
+ WTCP(0x7a659496, 0x2574fb36), WTCP(0x7a362220, 0x260eac6a), WTCP(0x7a05eead, 0x26a82186),
+ WTCP(0x79d4fa89, 0x27415996), WTCP(0x79a34602, 0x27da53a9), WTCP(0x7970d165, 0x28730ecd),
+ WTCP(0x793d9d03, 0x290b8a12), WTCP(0x7909a92d, 0x29a3c485), WTCP(0x78d4f634, 0x2a3bbd37),
+ WTCP(0x789f846b, 0x2ad37338), WTCP(0x78695428, 0x2b6ae598), WTCP(0x783265c0, 0x2c021369),
+ WTCP(0x77fab989, 0x2c98fbba), WTCP(0x77c24fdb, 0x2d2f9d9f), WTCP(0x77892910, 0x2dc5f829),
+ WTCP(0x774f4581, 0x2e5c0a6b), WTCP(0x7714a58b, 0x2ef1d377), WTCP(0x76d94989, 0x2f875262),
+ WTCP(0x769d31d9, 0x301c863f), WTCP(0x76605edb, 0x30b16e23), WTCP(0x7622d0ef, 0x31460922),
+ WTCP(0x75e48874, 0x31da5651), WTCP(0x75a585cf, 0x326e54c7), WTCP(0x7565c962, 0x3302039b),
+ WTCP(0x75255392, 0x339561e1), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74a23d62, 0x34bb2927),
+ WTCP(0x745f9dd1, 0x354d9057), WTCP(0x741c467b, 0x35dfa35a), WTCP(0x73d837ca, 0x3671614b),
+ WTCP(0x7393722a, 0x3702c942), WTCP(0x734df607, 0x3793da5b), WTCP(0x7307c3d0, 0x382493b0),
+ WTCP(0x72c0dbf3, 0x38b4f45d), WTCP(0x72793edf, 0x3944fb7e), WTCP(0x7230ed07, 0x39d4a82f),
+ WTCP(0x71e7e6dc, 0x3a63f98d), WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x7153bf5d, 0x3b8186ca),
+ WTCP(0x71089ef2, 0x3c0fc0e6), WTCP(0x70bccc09, 0x3c9d9c28), WTCP(0x70704718, 0x3d2b17b3),
+ WTCP(0x7023109a, 0x3db832a6), WTCP(0x6fd52907, 0x3e44ec22), WTCP(0x6f8690db, 0x3ed14349),
+ WTCP(0x6f374891, 0x3f5d373e), WTCP(0x6ee750a8, 0x3fe8c724), WTCP(0x6e96a99d, 0x4073f21d),
+ WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6df35020, 0x418915de), WTCP(0x6da09eb1, 0x42130cf0),
+ WTCP(0x6d4d4023, 0x429c9bab), WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6ca47dbf, 0x43ae7cb7),
+ WTCP(0x6c4f1af2, 0x4436cd58), WTCP(0x6bf90d1d, 0x44beb240), WTCP(0x6ba254c7, 0x45462a9a),
+ WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6af2e6bc, 0x4653d24b), WTCP(0x6a9a321d, 0x46d9fff8),
+ WTCP(0x6a40d527, 0x475fbdc3), WTCP(0x69e6d067, 0x47e50ad8), WTCP(0x698c246c, 0x4869e665),
+ WTCP(0x6930d1c4, 0x48ee4f98), WTCP(0x68d4d900, 0x497245a1), WTCP(0x68783ab1, 0x49f5c7ae),
+ WTCP(0x681af76a, 0x4a78d4f0), WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x675e843e, 0x4b7d8dd8),
+ WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x669f8425, 0x4c8069ea), WTCP(0x663f10b7, 0x4d012324),
+ WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x657c4613, 0x4e012800), WTCP(0x6519f010, 0x4e80720e),
+ WTCP(0x64b6fa66, 0x4eff4025), WTCP(0x645365b2, 0x4f7d917c), WTCP(0x63ef3290, 0x4ffb654d),
+ WTCP(0x638a619e, 0x5078bad1), WTCP(0x6324f37d, 0x50f59141), WTCP(0x62bee8cc, 0x5171e7d9),
+ WTCP(0x6258422c, 0x51edbdd4), WTCP(0x61f1003f, 0x5269126e), WTCP(0x618923a9, 0x52e3e4e6),
+ WTCP(0x6120ad0d, 0x535e3479), WTCP(0x60b79d10, 0x53d80065), WTCP(0x604df459, 0x545147eb),
+ WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5f78db56, 0x554246c6), WTCP(0x5f0d6c5b, 0x55b9fc9e),
+ WTCP(0x5ea16747, 0x56312b17), WTCP(0x5e34ccc3, 0x56a7d174), WTCP(0x5dc79d7c, 0x571deefa),
+ WTCP(0x5d59da1e, 0x579382ee), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5c7c99d1, 0x587d0b3b),
+ WTCP(0x5c0d1e41, 0x58f0fe23), WTCP(0x5b9d1154, 0x59646498), WTCP(0x5b2c73bb, 0x59d73de3),
+ WTCP(0x5abb4629, 0x5a498950),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow360[180] = {
+# else
+const PWord16 SineWindow360[180] = {
+# endif
+ WTCP(0x7fffec08, 0x00477d17), WTCP(0x7fff4c53, 0x00d676eb), WTCP(0x7ffe0cea, 0x01656fb4),
+ WTCP(0x7ffc2dcf, 0x01f466bf), WTCP(0x7ff9af03, 0x02835b59), WTCP(0x7ff6908a, 0x03124cd1),
+ WTCP(0x7ff2d268, 0x03a13a74), WTCP(0x7fee74a1, 0x0430238f), WTCP(0x7fe9773c, 0x04bf0771),
+ WTCP(0x7fe3da3d, 0x054de566), WTCP(0x7fdd9dac, 0x05dcbcbe), WTCP(0x7fd6c192, 0x066b8cc5),
+ WTCP(0x7fcf45f6, 0x06fa54c9), WTCP(0x7fc72ae1, 0x07891418), WTCP(0x7fbe705f, 0x0817ca01),
+ WTCP(0x7fb51679, 0x08a675d0), WTCP(0x7fab1d3c, 0x093516d4), WTCP(0x7fa084b4, 0x09c3ac5c),
+ WTCP(0x7f954cee, 0x0a5235b4), WTCP(0x7f8975f8, 0x0ae0b22c), WTCP(0x7f7cffe1, 0x0b6f2112),
+ WTCP(0x7f6feab8, 0x0bfd81b3), WTCP(0x7f62368e, 0x0c8bd35e), WTCP(0x7f53e374, 0x0d1a1562),
+ WTCP(0x7f44f17c, 0x0da8470d), WTCP(0x7f3560b8, 0x0e3667ad), WTCP(0x7f25313c, 0x0ec47692),
+ WTCP(0x7f14631c, 0x0f52730a), WTCP(0x7f02f66e, 0x0fe05c64), WTCP(0x7ef0eb45, 0x106e31ef),
+ WTCP(0x7ede41ba, 0x10fbf2fa), WTCP(0x7ecaf9e4, 0x11899ed3), WTCP(0x7eb713da, 0x121734cb),
+ WTCP(0x7ea28fb5, 0x12a4b431), WTCP(0x7e8d6d90, 0x13321c53), WTCP(0x7e77ad84, 0x13bf6c82),
+ WTCP(0x7e614fac, 0x144ca40e), WTCP(0x7e4a5425, 0x14d9c245), WTCP(0x7e32bb0b, 0x1566c679),
+ WTCP(0x7e1a847b, 0x15f3aff8), WTCP(0x7e01b095, 0x16807e14), WTCP(0x7de83f76, 0x170d301d),
+ WTCP(0x7dce313e, 0x1799c562), WTCP(0x7db3860e, 0x18263d35), WTCP(0x7d983e08, 0x18b296e7),
+ WTCP(0x7d7c594d, 0x193ed1c8), WTCP(0x7d5fd800, 0x19caed28), WTCP(0x7d42ba45, 0x1a56e85b),
+ WTCP(0x7d25003f, 0x1ae2c2b0), WTCP(0x7d06aa15, 0x1b6e7b7a), WTCP(0x7ce7b7ec, 0x1bfa1209),
+ WTCP(0x7cc829ea, 0x1c8585b0), WTCP(0x7ca80037, 0x1d10d5c1), WTCP(0x7c873afb, 0x1d9c018f),
+ WTCP(0x7c65da60, 0x1e27086a), WTCP(0x7c43de8d, 0x1eb1e9a6), WTCP(0x7c2147af, 0x1f3ca496),
+ WTCP(0x7bfe15f0, 0x1fc7388d), WTCP(0x7bda497c, 0x2051a4dd), WTCP(0x7bb5e27f, 0x20dbe8da),
+ WTCP(0x7b90e128, 0x216603d7), WTCP(0x7b6b45a4, 0x21eff528), WTCP(0x7b451022, 0x2279bc21),
+ WTCP(0x7b1e40d3, 0x23035817), WTCP(0x7af6d7e5, 0x238cc85c), WTCP(0x7aced58b, 0x24160c47),
+ WTCP(0x7aa639f7, 0x249f232b), WTCP(0x7a7d055a, 0x25280c5d), WTCP(0x7a5337e9, 0x25b0c734),
+ WTCP(0x7a28d1d8, 0x26395303), WTCP(0x79fdd35b, 0x26c1af21), WTCP(0x79d23ca9, 0x2749dae4),
+ WTCP(0x79a60df7, 0x27d1d5a2), WTCP(0x7979477c, 0x28599eb0), WTCP(0x794be972, 0x28e13566),
+ WTCP(0x791df40f, 0x2968991b), WTCP(0x78ef678e, 0x29efc925), WTCP(0x78c04429, 0x2a76c4dc),
+ WTCP(0x78908a1a, 0x2afd8b97), WTCP(0x7860399d, 0x2b841caf), WTCP(0x782f52ef, 0x2c0a777b),
+ WTCP(0x77fdd64b, 0x2c909b54), WTCP(0x77cbc3f1, 0x2d168792), WTCP(0x77991c1e, 0x2d9c3b8e),
+ WTCP(0x7765df12, 0x2e21b6a2), WTCP(0x77320d0c, 0x2ea6f826), WTCP(0x76fda64e, 0x2f2bff76),
+ WTCP(0x76c8ab18, 0x2fb0cbea), WTCP(0x76931bae, 0x30355cdc), WTCP(0x765cf850, 0x30b9b1a9),
+ WTCP(0x76264144, 0x313dc9aa), WTCP(0x75eef6ce, 0x31c1a43a), WTCP(0x75b71931, 0x324540b6),
+ WTCP(0x757ea8b5, 0x32c89e78), WTCP(0x7545a59f, 0x334bbcde), WTCP(0x750c1038, 0x33ce9b42),
+ WTCP(0x74d1e8c5, 0x34513903), WTCP(0x74972f91, 0x34d3957e), WTCP(0x745be4e4, 0x3555b00e),
+ WTCP(0x74200908, 0x35d78813), WTCP(0x73e39c48, 0x36591cea), WTCP(0x73a69ef0, 0x36da6df1),
+ WTCP(0x7369114b, 0x375b7a87), WTCP(0x732af3a6, 0x37dc420c), WTCP(0x72ec4650, 0x385cc3de),
+ WTCP(0x72ad0995, 0x38dcff5d), WTCP(0x726d3dc5, 0x395cf3e9), WTCP(0x722ce330, 0x39dca0e2),
+ WTCP(0x71ebfa25, 0x3a5c05aa), WTCP(0x71aa82f6, 0x3adb21a0), WTCP(0x71687df5, 0x3b59f428),
+ WTCP(0x7125eb74, 0x3bd87ca1), WTCP(0x70e2cbc5, 0x3c56ba70), WTCP(0x709f1f3d, 0x3cd4acf5),
+ WTCP(0x705ae630, 0x3d525394), WTCP(0x701620f4, 0x3dcfadaf), WTCP(0x6fd0cfdd, 0x3e4cbaac),
+ WTCP(0x6f8af343, 0x3ec979ed), WTCP(0x6f448b7d, 0x3f45ead7), WTCP(0x6efd98e2, 0x3fc20ccf),
+ WTCP(0x6eb61bcb, 0x403ddf39), WTCP(0x6e6e1492, 0x40b9617c), WTCP(0x6e25838f, 0x413492fd),
+ WTCP(0x6ddc691e, 0x41af7323), WTCP(0x6d92c59a, 0x422a0154), WTCP(0x6d48995f, 0x42a43cf7),
+ WTCP(0x6cfde4c9, 0x431e2573), WTCP(0x6cb2a836, 0x4397ba32), WTCP(0x6c66e403, 0x4410fa9a),
+ WTCP(0x6c1a988f, 0x4489e615), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6b806d61, 0x457abbe8),
+ WTCP(0x6b328e67, 0x45f2a513), WTCP(0x6ae429ad, 0x466a36f9), WTCP(0x6a953f94, 0x46e17102),
+ WTCP(0x6a45d080, 0x4758529c), WTCP(0x69f5dcd2, 0x47cedb30), WTCP(0x69a564ef, 0x48450a2d),
+ WTCP(0x6954693b, 0x48badefd), WTCP(0x6902ea1c, 0x4930590e), WTCP(0x68b0e7f6, 0x49a577ce),
+ WTCP(0x685e6331, 0x4a1a3aaa), WTCP(0x680b5c33, 0x4a8ea111), WTCP(0x67b7d363, 0x4b02aa71),
+ WTCP(0x6763c92b, 0x4b76563a), WTCP(0x670f3df2, 0x4be9a3db), WTCP(0x66ba3223, 0x4c5c92c4),
+ WTCP(0x6664a627, 0x4ccf2267), WTCP(0x660e9a69, 0x4d415233), WTCP(0x65b80f55, 0x4db3219c),
+ WTCP(0x65610557, 0x4e249011), WTCP(0x65097cda, 0x4e959d07), WTCP(0x64b1764d, 0x4f0647f0),
+ WTCP(0x6458f21d, 0x4f769040), WTCP(0x63fff0b9, 0x4fe6756a), WTCP(0x63a6728f, 0x5055f6e2),
+ WTCP(0x634c7810, 0x50c5141e), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x62970fd2, 0x51a21fb7),
+ WTCP(0x623ba2f6, 0x52100d01), WTCP(0x61dfbb89, 0x527d93e6), WTCP(0x618359fd, 0x52eab3de),
+ WTCP(0x61267ec7, 0x53576c62), WTCP(0x60c92a59, 0x53c3bce9), WTCP(0x606b5d28, 0x542fa4ed),
+ WTCP(0x600d17aa, 0x549b23e7), WTCP(0x5fae5a54, 0x55063950), WTCP(0x5f4f259c, 0x5570e4a3),
+ WTCP(0x5eef79f8, 0x55db255b), WTCP(0x5e8f57e2, 0x5644faf4), WTCP(0x5e2ebfcf, 0x56ae64e9),
+ WTCP(0x5dcdb239, 0x571762b6), WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5d0a3868, 0x57e817d1),
+ WTCP(0x5ca7cd21, 0x584fce19), WTCP(0x5c44ee3f, 0x58b71631), WTCP(0x5be19c3c, 0x591def98),
+ WTCP(0x5b7dd796, 0x598459ce), WTCP(0x5b19a0c7, 0x59ea5454), WTCP(0x5ab4f84f, 0x5a4fdea9),
+};
+
+# ifdef ENABLE_HR_MODE
+const PWord32 SineWindow480[240] = {
+# else
+const PWord16 SineWindow480[240] = {
+# endif
+ WTCP(0x7ffff4c5, 0x00359dd2), WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffee744, 0x010c1460),
+ WTCP(0x7ffdd9c4, 0x01774eb2), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ffab147, 0x024dbff4),
+ WTCP(0x7ff8964d, 0x02b8f64e), WTCP(0x7ff62182, 0x03242abf), WTCP(0x7ff352e8, 0x038f5cfb),
+ WTCP(0x7ff02a82, 0x03fa8cb8), WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe8cc57, 0x04d0e386),
+ WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fdb1dd5, 0x06124ba5),
+ WTCP(0x7fd5dad8, 0x067d6639), WTCP(0x7fd03e23, 0x06e87c3f), WTCP(0x7fca47b9, 0x07538d6b),
+ WTCP(0x7fc3f7a0, 0x07be9973), WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fb64a6e, 0x0894a0ea),
+ WTCP(0x7faeed5f, 0x08ff9bc2), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f9f2671, 0x09d57e35),
+ WTCP(0x7f96bc9c, 0x0a40653a), WTCP(0x7f8df93c, 0x0aab450d), WTCP(0x7f84dc55, 0x0b161d63),
+ WTCP(0x7f7b65ef, 0x0b80edf1), WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f676cc0, 0x0c56768a),
+ WTCP(0x7f5cea05, 0x0cc12dff), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f46d86c, 0x0d9681c2),
+ WTCP(0x7f3b499d, 0x0e011d7c), WTCP(0x7f2f6183, 0x0e6baf61), WTCP(0x7f232026, 0x0ed63727),
+ WTCP(0x7f16858e, 0x0f40b483), WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7efc44d0, 0x10158ed4),
+ WTCP(0x7eee9ebe, 0x107feb33), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7ed24761, 0x115480e9),
+ WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7eb48bfb, 0x1228e5f8), WTCP(0x7ea528e0, 0x12930586),
+ WTCP(0x7e956ce1, 0x12fd180b), WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e74ea6a, 0x13d114d0),
+ WTCP(0x7e642408, 0x143afe7b), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e418d32, 0x150ea6ef),
+ WTCP(0x7e2fbcd6, 0x15786522), WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7e0b127a, 0x164bb40b),
+ WTCP(0x7df83895, 0x16b5442b), WTCP(0x7de50646, 0x171ec45c), WTCP(0x7dd17b9c, 0x17883452),
+ WTCP(0x7dbd98a4, 0x17f193c5), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d94ca03, 0x18c41ff6),
+ WTCP(0x7d7fde76, 0x192d4c21), WTCP(0x7d6a9ad5, 0x199666a0), WTCP(0x7d54ff2e, 0x19ff6f2a),
+ WTCP(0x7d3f0b90, 0x1a686575), WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7d121cb0, 0x1b3a1a28),
+ WTCP(0x7cfb218c, 0x1ba2d7fc), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7ccc2430, 0x1c74192a),
+ WTCP(0x7cb42217, 0x1cdc9bf2), WTCP(0x7c9bc87a, 0x1d450a78), WTCP(0x7c831767, 0x1dad6473),
+ WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c36f824, 0x1ee5f447),
+ WTCP(0x7c1ce9ef, 0x1f4df93a), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7be7c847, 0x201dc0ef),
+ WTCP(0x7bccb4f8, 0x2085831f), WTCP(0x7bb14ac5, 0x20ed2e7b), WTCP(0x7b9589c3, 0x2154c2bb),
+ WTCP(0x7b797205, 0x21bc3f97), WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b403ea2, 0x228af1fe),
+ WTCP(0x7b232325, 0x22f226f8), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7ae7e8fc, 0x23c04710),
+ WTCP(0x7ac9ca7a, 0x2427319d), WTCP(0x7aab55ca, 0x248e02cb), WTCP(0x7a8c8b01, 0x24f4ba50),
+ WTCP(0x7a6d6a37, 0x255b57e6), WTCP(0x7a4df380, 0x25c1db44), WTCP(0x7a2e26f2, 0x26284422),
+ WTCP(0x7a0e04a4, 0x268e9238), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x79ccbf22, 0x275adcee),
+ WTCP(0x79ab9c1c, 0x27c0d8fe), WTCP(0x798a23b1, 0x2826b928), WTCP(0x796855f9, 0x288c7d24),
+ WTCP(0x7946330c, 0x28f224ab), WTCP(0x7923bb01, 0x2957af74), WTCP(0x7900edf2, 0x29bd1d3a),
+ WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x78968998, 0x2aecb5ac),
+ WTCP(0x7872696a, 0x2b51ac9a), WTCP(0x784df4b3, 0x2bb68522), WTCP(0x78292b8d, 0x2c1b3efb),
+ WTCP(0x78040e12, 0x2c7fd9e0), WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x77b8d683, 0x2d48b1b1),
+ WTCP(0x7792bca5, 0x2dacee11), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x77458d40, 0x2e75065e),
+ WTCP(0x771e77f0, 0x2ed8e1c0), WTCP(0x76f70f05, 0x2f3c9c40), WTCP(0x76cf529c, 0x2fa03599),
+ WTCP(0x76a742d1, 0x3003ad85), WTCP(0x767edfbe, 0x306703bf), WTCP(0x76562982, 0x30ca3800),
+ WTCP(0x762d2038, 0x312d4a03), WTCP(0x7603c3fd, 0x31903982), WTCP(0x75da14ef, 0x31f30638),
+ WTCP(0x75b01329, 0x3255afe0), WTCP(0x7585becb, 0x32b83634), WTCP(0x755b17f2, 0x331a98ef),
+ WTCP(0x75301ebb, 0x337cd7cd), WTCP(0x7504d345, 0x33def287), WTCP(0x74d935ae, 0x3440e8da),
+ WTCP(0x74ad4615, 0x34a2ba81), WTCP(0x74810499, 0x35046736), WTCP(0x74547158, 0x3565eeb6),
+ WTCP(0x74278c72, 0x35c750bc), WTCP(0x73fa5607, 0x36288d03), WTCP(0x73ccce36, 0x3689a348),
+ WTCP(0x739ef51f, 0x36ea9346), WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x73424fa0, 0x37abff5d),
+ WTCP(0x73138379, 0x380c7aee), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72b4f902, 0x38ccfbcb),
+ WTCP(0x72853af3, 0x392d008f), WTCP(0x72552c85, 0x398cdd32), WTCP(0x7224cdd8, 0x39ec9172),
+ WTCP(0x71f41f0f, 0x3a4c1d09), WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x7191d1b1, 0x3b0ab937),
+ WTCP(0x71603361, 0x3b69c947), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70fc082d, 0x3c276c0d),
+ WTCP(0x70c97b90, 0x3c85fe3d), WTCP(0x70969fca, 0x3ce465f3), WTCP(0x706374ff, 0x3d42a2ec),
+ WTCP(0x702ffb54, 0x3da0b4e7), WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6fc81bea, 0x3e5c56d8),
+ WTCP(0x6f93b676, 0x3eb9e64b), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6f2a00c4, 0x3f7480dd),
+ WTCP(0x6ef4b0d1, 0x3fd18b7a), WTCP(0x6ebf12ff, 0x402e694c), WTCP(0x6e892772, 0x408b1a12),
+ WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6de593ee, 0x41a01b97),
+ WTCP(0x6dae72f7, 0x41fc15a6), WTCP(0x6d770506, 0x4257e166), WTCP(0x6d3f4a40, 0x42b37e96),
+ WTCP(0x6d0742cf, 0x430eecf6), WTCP(0x6cceeed8, 0x436a2c45), WTCP(0x6c964e83, 0x43c53c44),
+ WTCP(0x6c5d61f9, 0x44201cb2), WTCP(0x6c242960, 0x447acd50), WTCP(0x6beaa4e2, 0x44d54ddf),
+ WTCP(0x6bb0d4a7, 0x452f9e1e), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6b3c519a, 0x45e3acb1),
+ WTCP(0x6b019f1a, 0x463d6a87), WTCP(0x6ac6a180, 0x4696f710), WTCP(0x6a8b58f6, 0x46f0520f),
+ WTCP(0x6a4fc5a6, 0x47497b44), WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x69d7bf57, 0x47fb3757),
+ WTCP(0x699b4cad, 0x4853c9b9), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x69218929, 0x490455f4),
+ WTCP(0x68e438a4, 0x495c4f52), WTCP(0x68a69e81, 0x49b41533), WTCP(0x6868baec, 0x4a0ba75b),
+ WTCP(0x682a8e0f, 0x4a63058a), WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x67ad592f, 0x4b11250c),
+ WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x66ef6891, 0x4c14c894),
+ WTCP(0x66af87a4, 0x4c6ae9f2), WTCP(0x666f5ea6, 0x4cc0d5ae), WTCP(0x662eedc3, 0x4d168b8b),
+ WTCP(0x65ee3529, 0x4d6c0b4e), WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x656bed84, 0x4e166795),
+ WTCP(0x652a5ed6, 0x4e6b43a2), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64a66ca5, 0x4f145662),
+ WTCP(0x6464097f, 0x4f688ca0), WTCP(0x64215fe5, 0x4fbc8b22), WTCP(0x63de7003, 0x501051ae),
+ WTCP(0x639b3a0b, 0x5063e008), WTCP(0x6357be2a, 0x50b735f8), WTCP(0x6313fc90, 0x510a5340),
+ WTCP(0x62cff56c, 0x515d37a9), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x62471749, 0x520254ef),
+ WTCP(0x620240a8, 0x52548d59), WTCP(0x61bd253f, 0x52a68bfb), WTCP(0x6177c53c, 0x52f8509b),
+ WTCP(0x613220d2, 0x5349daff), WTCP(0x60ec3830, 0x539b2af0), WTCP(0x60a60b88, 0x53ec4032),
+ WTCP(0x605f9b0b, 0x543d1a8e), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5fd1ef59, 0x54de1db1),
+ WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5f4336a7, 0x557e3292), WTCP(0x5efb75ea, 0x55cde31e),
+ WTCP(0x5eb37285, 0x561d5771), WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5e22a487, 0x56bb8a90),
+ WTCP(0x5dd9da55, 0x570a48ec), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5d47808a, 0x57a70e29),
+ WTCP(0x5cfdf157, 0x57f5149d), WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5c6a0f59, 0x5890681a),
+ WTCP(0x5c1fbcf6, 0x58ddb4b8), WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5b8a566c, 0x597792a1),
+ WTCP(0x5b3f42ae, 0x59c42381), WTCP(0x5af3eee6, 0x5a107561), WTCP(0x5aa85b48, 0x5a5c880a),
+};
+
+# ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+const PWord32 SineWindow720[360] = {
+ WTCP(0x7ffffb01, 0x0023be8d), WTCP(0x7fffd314, 0x006b3b9b), WTCP(0x7fff833a, 0x00b2b888),
+ WTCP(0x7fff0b72, 0x00fa353e), WTCP(0x7ffe6bbe, 0x0141b1a5), WTCP(0x7ffda41c, 0x01892da8),
+ WTCP(0x7ffcb48e, 0x01d0a930), WTCP(0x7ffb9d14, 0x02182427), WTCP(0x7ffa5dae, 0x025f9e77),
+ WTCP(0x7ff8f65d, 0x02a7180a), WTCP(0x7ff76720, 0x02ee90c8), WTCP(0x7ff5aff9, 0x0336089d),
+ WTCP(0x7ff3d0e8, 0x037d7f71), WTCP(0x7ff1c9ee, 0x03c4f52e), WTCP(0x7fef9b0a, 0x040c69bf),
+ WTCP(0x7fed443f, 0x0453dd0c), WTCP(0x7feac58c, 0x049b4f00), WTCP(0x7fe81ef2, 0x04e2bf83),
+ WTCP(0x7fe55073, 0x052a2e81), WTCP(0x7fe25a0e, 0x05719be2), WTCP(0x7fdf3bc6, 0x05b90791),
+ WTCP(0x7fdbf59a, 0x06007176), WTCP(0x7fd8878d, 0x0647d97c), WTCP(0x7fd4f19f, 0x068f3f8d),
+ WTCP(0x7fd133d0, 0x06d6a392), WTCP(0x7fcd4e23, 0x071e0575), WTCP(0x7fc94099, 0x0765651f),
+ WTCP(0x7fc50b33, 0x07acc27b), WTCP(0x7fc0adf1, 0x07f41d72), WTCP(0x7fbc28d6, 0x083b75ee),
+ WTCP(0x7fb77be3, 0x0882cbd8), WTCP(0x7fb2a71a, 0x08ca1f1b), WTCP(0x7fadaa7b, 0x09116fa0),
+ WTCP(0x7fa88608, 0x0958bd51), WTCP(0x7fa339c4, 0x09a00817), WTCP(0x7f9dc5b0, 0x09e74fdd),
+ WTCP(0x7f9829cc, 0x0a2e948c), WTCP(0x7f92661c, 0x0a75d60e), WTCP(0x7f8c7aa1, 0x0abd144d),
+ WTCP(0x7f86675c, 0x0b044f32), WTCP(0x7f802c51, 0x0b4b86a8), WTCP(0x7f79c980, 0x0b92ba97),
+ WTCP(0x7f733eeb, 0x0bd9eaeb), WTCP(0x7f6c8c95, 0x0c21178c), WTCP(0x7f65b280, 0x0c684064),
+ WTCP(0x7f5eb0ae, 0x0caf655e), WTCP(0x7f578720, 0x0cf68662), WTCP(0x7f5035da, 0x0d3da35c),
+ WTCP(0x7f48bcde, 0x0d84bc34), WTCP(0x7f411c2e, 0x0dcbd0d5), WTCP(0x7f3953cb, 0x0e12e128),
+ WTCP(0x7f3163ba, 0x0e59ed17), WTCP(0x7f294bfc, 0x0ea0f48c), WTCP(0x7f210c93, 0x0ee7f771),
+ WTCP(0x7f18a583, 0x0f2ef5b0), WTCP(0x7f1016cd, 0x0f75ef32), WTCP(0x7f076075, 0x0fbce3e2),
+ WTCP(0x7efe827e, 0x1003d3a9), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7eec4fbb, 0x1091a424),
+ WTCP(0x7ee2faf5, 0x10d884ad), WTCP(0x7ed97e9b, 0x111f5ff3), WTCP(0x7ecfdaaf, 0x116635e3),
+ WTCP(0x7ec60f35, 0x11ad0665), WTCP(0x7ebc1c30, 0x11f3d164), WTCP(0x7eb201a2, 0x123a96c9),
+ WTCP(0x7ea7bf90, 0x1281567f), WTCP(0x7e9d55fb, 0x12c8106e), WTCP(0x7e92c4e8, 0x130ec482),
+ WTCP(0x7e880c5a, 0x135572a5), WTCP(0x7e7d2c53, 0x139c1abf), WTCP(0x7e7224d8, 0x13e2bcbb),
+ WTCP(0x7e66f5ec, 0x14295884), WTCP(0x7e5b9f92, 0x146fee02), WTCP(0x7e5021ce, 0x14b67d21),
+ WTCP(0x7e447ca3, 0x14fd05c9), WTCP(0x7e38b016, 0x154387e6), WTCP(0x7e2cbc29, 0x158a0360),
+ WTCP(0x7e20a0e1, 0x15d07823), WTCP(0x7e145e41, 0x1616e618), WTCP(0x7e07f44d, 0x165d4d28),
+ WTCP(0x7dfb6309, 0x16a3ad3f), WTCP(0x7deeaa79, 0x16ea0646), WTCP(0x7de1caa1, 0x17305827),
+ WTCP(0x7dd4c384, 0x1776a2cd), WTCP(0x7dc79528, 0x17bce621), WTCP(0x7dba3f90, 0x1803220d),
+ WTCP(0x7dacc2c0, 0x1849567c), WTCP(0x7d9f1ebc, 0x188f8357), WTCP(0x7d915389, 0x18d5a889),
+ WTCP(0x7d83612b, 0x191bc5fc), WTCP(0x7d7547a6, 0x1961db9b), WTCP(0x7d6706ff, 0x19a7e94e),
+ WTCP(0x7d589f3a, 0x19edef00), WTCP(0x7d4a105c, 0x1a33ec9c), WTCP(0x7d3b5a69, 0x1a79e20c),
+ WTCP(0x7d2c7d66, 0x1abfcf39), WTCP(0x7d1d7957, 0x1b05b40e), WTCP(0x7d0e4e41, 0x1b4b9076),
+ WTCP(0x7cfefc29, 0x1b91645a), WTCP(0x7cef8314, 0x1bd72fa4), WTCP(0x7cdfe306, 0x1c1cf23f),
+ WTCP(0x7cd01c05, 0x1c62ac16), WTCP(0x7cc02e14, 0x1ca85d12), WTCP(0x7cb0193a, 0x1cee051d),
+ WTCP(0x7c9fdd7b, 0x1d33a422), WTCP(0x7c8f7add, 0x1d793a0b), WTCP(0x7c7ef164, 0x1dbec6c3),
+ WTCP(0x7c6e4115, 0x1e044a33), WTCP(0x7c5d69f6, 0x1e49c447), WTCP(0x7c4c6c0d, 0x1e8f34e8),
+ WTCP(0x7c3b475d, 0x1ed49c00), WTCP(0x7c29fbed, 0x1f19f97b), WTCP(0x7c1889c3, 0x1f5f4d42),
+ WTCP(0x7c06f0e2, 0x1fa49740), WTCP(0x7bf53152, 0x1fe9d75f), WTCP(0x7be34b17, 0x202f0d8a),
+ WTCP(0x7bd13e38, 0x207439aa), WTCP(0x7bbf0ab9, 0x20b95bac), WTCP(0x7bacb0a0, 0x20fe7378),
+ WTCP(0x7b9a2ff4, 0x214380f9), WTCP(0x7b8788b9, 0x2188841a), WTCP(0x7b74baf7, 0x21cd7cc5),
+ WTCP(0x7b61c6b2, 0x22126ae5), WTCP(0x7b4eabf0, 0x22574e65), WTCP(0x7b3b6ab8, 0x229c272e),
+ WTCP(0x7b28030f, 0x22e0f52b), WTCP(0x7b1474fc, 0x2325b847), WTCP(0x7b00c085, 0x236a706d),
+ WTCP(0x7aece5af, 0x23af1d86), WTCP(0x7ad8e481, 0x23f3bf7e), WTCP(0x7ac4bd02, 0x2438563f),
+ WTCP(0x7ab06f36, 0x247ce1b4), WTCP(0x7a9bfb26, 0x24c161c7), WTCP(0x7a8760d7, 0x2505d663),
+ WTCP(0x7a72a050, 0x254a3f72), WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a48acb2, 0x25d2ee97),
+ WTCP(0x7a3379a8, 0x26173481), WTCP(0x7a1e2081, 0x265b6e8a), WTCP(0x7a08a141, 0x269f9c9c),
+ WTCP(0x79f2fbf1, 0x26e3bea1), WTCP(0x79dd3097, 0x2727d485), WTCP(0x79c73f3a, 0x276bde33),
+ WTCP(0x79b127e0, 0x27afdb94), WTCP(0x799aea91, 0x27f3cc94), WTCP(0x79848753, 0x2837b11e),
+ WTCP(0x796dfe2d, 0x287b891c), WTCP(0x79574f27, 0x28bf547a), WTCP(0x79407a47, 0x29031322),
+ WTCP(0x79297f95, 0x2946c4ff), WTCP(0x79125f18, 0x298a69fc), WTCP(0x78fb18d6, 0x29ce0204),
+ WTCP(0x78e3acd8, 0x2a118d01), WTCP(0x78cc1b25, 0x2a550adf), WTCP(0x78b463c3, 0x2a987b89),
+ WTCP(0x789c86bb, 0x2adbdee9), WTCP(0x78848413, 0x2b1f34eb), WTCP(0x786c5bd4, 0x2b627d79),
+ WTCP(0x78540e04, 0x2ba5b87f), WTCP(0x783b9aac, 0x2be8e5e8), WTCP(0x782301d2, 0x2c2c059e),
+ WTCP(0x780a4380, 0x2c6f178d), WTCP(0x77f15fbb, 0x2cb21ba0), WTCP(0x77d8568d, 0x2cf511c2),
+ WTCP(0x77bf27fd, 0x2d37f9dd), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x778c5ad6, 0x2dbd9faf),
+ WTCP(0x7772bc4f, 0x2e005d3c), WTCP(0x7758f885, 0x2e430c6f), WTCP(0x773f0f81, 0x2e85ad34),
+ WTCP(0x7725014b, 0x2ec83f76), WTCP(0x770acdeb, 0x2f0ac320), WTCP(0x76f07569, 0x2f4d381e),
+ WTCP(0x76d5f7cd, 0x2f8f9e5a), WTCP(0x76bb5520, 0x2fd1f5c1), WTCP(0x76a08d6a, 0x30143e3d),
+ WTCP(0x7685a0b2, 0x305677ba), WTCP(0x766a8f03, 0x3098a222), WTCP(0x764f5863, 0x30dabd63),
+ WTCP(0x7633fcdc, 0x311cc966), WTCP(0x76187c76, 0x315ec617), WTCP(0x75fcd739, 0x31a0b362),
+ WTCP(0x75e10d2f, 0x31e29131), WTCP(0x75c51e60, 0x32245f72), WTCP(0x75a90ad4, 0x32661e0e),
+ WTCP(0x758cd295, 0x32a7ccf2), WTCP(0x757075ab, 0x32e96c09), WTCP(0x7553f41f, 0x332afb3e),
+ WTCP(0x75374dfa, 0x336c7a7d), WTCP(0x751a8345, 0x33ade9b2), WTCP(0x74fd9409, 0x33ef48c8),
+ WTCP(0x74e0804f, 0x343097ab), WTCP(0x74c3481f, 0x3471d647), WTCP(0x74a5eb84, 0x34b30487),
+ WTCP(0x74886a86, 0x34f42256), WTCP(0x746ac52e, 0x35352fa1), WTCP(0x744cfb86, 0x35762c53),
+ WTCP(0x742f0d97, 0x35b71858), WTCP(0x7410fb6a, 0x35f7f39b), WTCP(0x73f2c509, 0x3638be09),
+ WTCP(0x73d46a7d, 0x3679778d), WTCP(0x73b5ebd0, 0x36ba2013), WTCP(0x7397490b, 0x36fab787),
+ WTCP(0x73788237, 0x373b3dd5), WTCP(0x7359975f, 0x377bb2e8), WTCP(0x733a888b, 0x37bc16ad),
+ WTCP(0x731b55c6, 0x37fc690f), WTCP(0x72fbff1a, 0x383ca9fb), WTCP(0x72dc848f, 0x387cd95b),
+ WTCP(0x72bce631, 0x38bcf71d), WTCP(0x729d2408, 0x38fd032d), WTCP(0x727d3e1f, 0x393cfd75),
+ WTCP(0x725d347f, 0x397ce5e3), WTCP(0x723d0733, 0x39bcbc62), WTCP(0x721cb645, 0x39fc80df),
+ WTCP(0x71fc41be, 0x3a3c3345), WTCP(0x71dba9aa, 0x3a7bd381), WTCP(0x71baee11, 0x3abb617f),
+ WTCP(0x719a0eff, 0x3afadd2b), WTCP(0x71790c7d, 0x3b3a4671), WTCP(0x7157e696, 0x3b799d3e),
+ WTCP(0x71369d54, 0x3bb8e17d), WTCP(0x711530c1, 0x3bf8131b), WTCP(0x70f3a0e8, 0x3c373205),
+ WTCP(0x70d1edd4, 0x3c763e26), WTCP(0x70b0178f, 0x3cb5376b), WTCP(0x708e1e23, 0x3cf41dc0),
+ WTCP(0x706c019b, 0x3d32f112), WTCP(0x7049c202, 0x3d71b14d), WTCP(0x70275f63, 0x3db05e5d),
+ WTCP(0x7004d9c7, 0x3deef830), WTCP(0x6fe2313b, 0x3e2d7eb0), WTCP(0x6fbf65c8, 0x3e6bf1cc),
+ WTCP(0x6f9c7779, 0x3eaa516f), WTCP(0x6f79665a, 0x3ee89d86), WTCP(0x6f563276, 0x3f26d5fd),
+ WTCP(0x6f32dbd7, 0x3f64fac2), WTCP(0x6f0f6288, 0x3fa30bc0), WTCP(0x6eebc694, 0x3fe108e5),
+ WTCP(0x6ec80808, 0x401ef21d), WTCP(0x6ea426ed, 0x405cc754), WTCP(0x6e80234e, 0x409a8878),
+ WTCP(0x6e5bfd38, 0x40d83575), WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6e1349d2, 0x415352ad),
+ WTCP(0x6deebc98, 0x4190c2c3), WTCP(0x6dca0d14, 0x41ce1e64), WTCP(0x6da53b50, 0x420b657f),
+ WTCP(0x6d804759, 0x42489800), WTCP(0x6d5b313a, 0x4285b5d4), WTCP(0x6d35f8ff, 0x42c2bee7),
+ WTCP(0x6d109eb2, 0x42ffb328), WTCP(0x6ceb2260, 0x433c9283), WTCP(0x6cc58415, 0x43795ce4),
+ WTCP(0x6c9fc3dc, 0x43b6123a), WTCP(0x6c79e1c1, 0x43f2b270), WTCP(0x6c53ddd0, 0x442f3d75),
+ WTCP(0x6c2db815, 0x446bb335), WTCP(0x6c07709b, 0x44a8139d), WTCP(0x6be1076e, 0x44e45e9b),
+ WTCP(0x6bba7c9b, 0x4520941b), WTCP(0x6b93d02d, 0x455cb40c), WTCP(0x6b6d0232, 0x4598be59),
+ WTCP(0x6b4612b3, 0x45d4b2f1), WTCP(0x6b1f01bf, 0x461091c1), WTCP(0x6af7cf60, 0x464c5ab6),
+ WTCP(0x6ad07ba4, 0x46880dbd), WTCP(0x6aa90696, 0x46c3aac5), WTCP(0x6a817043, 0x46ff31b9),
+ WTCP(0x6a59b8b7, 0x473aa288), WTCP(0x6a31dfff, 0x4775fd1f), WTCP(0x6a09e626, 0x47b1416c),
+ WTCP(0x69e1cb3a, 0x47ec6f5b), WTCP(0x69b98f47, 0x482786dc), WTCP(0x6991325a, 0x486287da),
+ WTCP(0x6968b47e, 0x489d7245), WTCP(0x694015c2, 0x48d84609), WTCP(0x69175630, 0x49130314),
+ WTCP(0x68ee75d7, 0x494da953), WTCP(0x68c574c3, 0x498838b6), WTCP(0x689c5300, 0x49c2b128),
+ WTCP(0x6873109c, 0x49fd1298), WTCP(0x6849ada3, 0x4a375cf4), WTCP(0x68202a22, 0x4a71902a),
+ WTCP(0x67f68626, 0x4aabac27), WTCP(0x67ccc1bd, 0x4ae5b0d9), WTCP(0x67a2dcf3, 0x4b1f9e2f),
+ WTCP(0x6778d7d5, 0x4b597416), WTCP(0x674eb270, 0x4b93327b), WTCP(0x67246cd3, 0x4bccd94e),
+ WTCP(0x66fa0708, 0x4c06687c), WTCP(0x66cf811f, 0x4c3fdff3), WTCP(0x66a4db24, 0x4c793fa1),
+ WTCP(0x667a1524, 0x4cb28775), WTCP(0x664f2f2e, 0x4cebb75c), WTCP(0x6624294d, 0x4d24cf44),
+ WTCP(0x65f90390, 0x4d5dcf1c), WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x65a258b7, 0x4dcf8655),
+ WTCP(0x6576d3b6, 0x4e083d93), WTCP(0x654b2f0f, 0x4e40dc78), WTCP(0x651f6acf, 0x4e7962f6),
+ WTCP(0x64f38704, 0x4eb1d0f8), WTCP(0x64c783bc, 0x4eea266f), WTCP(0x649b6104, 0x4f226348),
+ WTCP(0x646f1eeb, 0x4f5a8772), WTCP(0x6442bd7d, 0x4f9292db), WTCP(0x64163cc9, 0x4fca8572),
+ WTCP(0x63e99cdd, 0x50025f26), WTCP(0x63bcddc6, 0x503a1fe4), WTCP(0x638fff93, 0x5071c79c),
+ WTCP(0x63630252, 0x50a9563d), WTCP(0x6335e610, 0x50e0cbb4), WTCP(0x6308aadc, 0x511827f0),
+ WTCP(0x62db50c4, 0x514f6ae1), WTCP(0x62add7d5, 0x51869476), WTCP(0x6280401f, 0x51bda49c),
+ WTCP(0x625289af, 0x51f49b42), WTCP(0x6224b494, 0x522b7859), WTCP(0x61f6c0dc, 0x52623bcd),
+ WTCP(0x61c8ae94, 0x5298e58f), WTCP(0x619a7dcd, 0x52cf758e), WTCP(0x616c2e93, 0x5305ebb8),
+ WTCP(0x613dc0f6, 0x533c47fc), WTCP(0x610f3504, 0x53728a49), WTCP(0x60e08acb, 0x53a8b28f),
+ WTCP(0x60b1c25b, 0x53dec0bc), WTCP(0x6082dbc0, 0x5414b4c0), WTCP(0x6053d70c, 0x544a8e8a),
+ WTCP(0x6024b44b, 0x54804e09), WTCP(0x5ff5738c, 0x54b5f32c), WTCP(0x5fc614df, 0x54eb7de2),
+ WTCP(0x5f969852, 0x5520ee1c), WTCP(0x5f66fdf4, 0x555643c8), WTCP(0x5f3745d4, 0x558b7ed5),
+ WTCP(0x5f077001, 0x55c09f33), WTCP(0x5ed77c89, 0x55f5a4d2), WTCP(0x5ea76b7c, 0x562a8fa0),
+ WTCP(0x5e773ce8, 0x565f5f8e), WTCP(0x5e46f0dc, 0x5694148a), WTCP(0x5e168769, 0x56c8ae85),
+ WTCP(0x5de6009c, 0x56fd2d6e), WTCP(0x5db55c85, 0x57319134), WTCP(0x5d849b33, 0x5765d9c8),
+ WTCP(0x5d53bcb5, 0x579a0719), WTCP(0x5d22c11b, 0x57ce1916), WTCP(0x5cf1a874, 0x58020fb0),
+ WTCP(0x5cc072ce, 0x5835ead6), WTCP(0x5c8f203a, 0x5869aa78), WTCP(0x5c5db0c7, 0x589d4e87),
+ WTCP(0x5c2c2484, 0x58d0d6f0), WTCP(0x5bfa7b81, 0x590443a6), WTCP(0x5bc8b5cd, 0x59379497),
+ WTCP(0x5b96d378, 0x596ac9b5), WTCP(0x5b64d491, 0x599de2ed), WTCP(0x5b32b928, 0x59d0e032),
+ WTCP(0x5b00814c, 0x5a03c172), WTCP(0x5ace2d0e, 0x5a36869f), WTCP(0x5a9bbc7c, 0x5a692fa7)
+};
+#endif
+
+const PWord32 SineWindow960[480] = {
+ WTCP(0x7ffffd30, 0x001aceea), WTCP(0x7fffe6bb, 0x00506cb9), WTCP(0x7fffb9d0, 0x00860a79),
+ WTCP(0x7fff7670, 0x00bba822), WTCP(0x7fff1c9a, 0x00f145ab), WTCP(0x7ffeac4f, 0x0126e309),
+ WTCP(0x7ffe258f, 0x015c8033), WTCP(0x7ffd8859, 0x01921d20), WTCP(0x7ffcd4af, 0x01c7b9c6),
+ WTCP(0x7ffc0a90, 0x01fd561d), WTCP(0x7ffb29fc, 0x0232f21a), WTCP(0x7ffa32f3, 0x02688db4),
+ WTCP(0x7ff92576, 0x029e28e2), WTCP(0x7ff80185, 0x02d3c39b), WTCP(0x7ff6c71f, 0x03095dd5),
+ WTCP(0x7ff57646, 0x033ef786), WTCP(0x7ff40ef9, 0x037490a5), WTCP(0x7ff29139, 0x03aa292a),
+ WTCP(0x7ff0fd06, 0x03dfc109), WTCP(0x7fef525f, 0x0415583b), WTCP(0x7fed9147, 0x044aeeb5),
+ WTCP(0x7febb9bc, 0x0480846e), WTCP(0x7fe9cbbf, 0x04b6195d), WTCP(0x7fe7c751, 0x04ebad79),
+ WTCP(0x7fe5ac71, 0x052140b7), WTCP(0x7fe37b21, 0x0556d30f), WTCP(0x7fe13360, 0x058c6478),
+ WTCP(0x7fded52f, 0x05c1f4e7), WTCP(0x7fdc608e, 0x05f78453), WTCP(0x7fd9d57e, 0x062d12b3),
+ WTCP(0x7fd73400, 0x06629ffe), WTCP(0x7fd47c13, 0x06982c2b), WTCP(0x7fd1adb8, 0x06cdb72f),
+ WTCP(0x7fcec8f0, 0x07034101), WTCP(0x7fcbcdbb, 0x0738c998), WTCP(0x7fc8bc1a, 0x076e50eb),
+ WTCP(0x7fc5940d, 0x07a3d6f0), WTCP(0x7fc25595, 0x07d95b9e), WTCP(0x7fbf00b2, 0x080edeec),
+ WTCP(0x7fbb9566, 0x084460cf), WTCP(0x7fb813af, 0x0879e140), WTCP(0x7fb47b90, 0x08af6033),
+ WTCP(0x7fb0cd09, 0x08e4dda0), WTCP(0x7fad081a, 0x091a597e), WTCP(0x7fa92cc4, 0x094fd3c3),
+ WTCP(0x7fa53b08, 0x09854c66), WTCP(0x7fa132e7, 0x09bac35d), WTCP(0x7f9d1460, 0x09f0389f),
+ WTCP(0x7f98df76, 0x0a25ac22), WTCP(0x7f949428, 0x0a5b1dde), WTCP(0x7f903278, 0x0a908dc9),
+ WTCP(0x7f8bba65, 0x0ac5fbd9), WTCP(0x7f872bf2, 0x0afb6805), WTCP(0x7f82871e, 0x0b30d244),
+ WTCP(0x7f7dcbeb, 0x0b663a8c), WTCP(0x7f78fa5a, 0x0b9ba0d5), WTCP(0x7f74126a, 0x0bd10513),
+ WTCP(0x7f6f141e, 0x0c06673f), WTCP(0x7f69ff75, 0x0c3bc74f), WTCP(0x7f64d472, 0x0c71253a),
+ WTCP(0x7f5f9314, 0x0ca680f5), WTCP(0x7f5a3b5d, 0x0cdbda79), WTCP(0x7f54cd4e, 0x0d1131ba),
+ WTCP(0x7f4f48e7, 0x0d4686b1), WTCP(0x7f49ae29, 0x0d7bd954), WTCP(0x7f43fd17, 0x0db12998),
+ WTCP(0x7f3e35af, 0x0de67776), WTCP(0x7f3857f5, 0x0e1bc2e4), WTCP(0x7f3263e8, 0x0e510bd7),
+ WTCP(0x7f2c5989, 0x0e865248), WTCP(0x7f2638da, 0x0ebb962c), WTCP(0x7f2001dc, 0x0ef0d77b),
+ WTCP(0x7f19b490, 0x0f26162a), WTCP(0x7f1350f7, 0x0f5b5231), WTCP(0x7f0cd711, 0x0f908b86),
+ WTCP(0x7f0646e1, 0x0fc5c220), WTCP(0x7effa068, 0x0ffaf5f6), WTCP(0x7ef8e3a5, 0x103026fe),
+ WTCP(0x7ef2109c, 0x1065552e), WTCP(0x7eeb274c, 0x109a807e), WTCP(0x7ee427b8, 0x10cfa8e5),
+ WTCP(0x7edd11e0, 0x1104ce58), WTCP(0x7ed5e5c5, 0x1139f0cf), WTCP(0x7ecea36a, 0x116f1040),
+ WTCP(0x7ec74ace, 0x11a42ca2), WTCP(0x7ebfdbf4, 0x11d945eb), WTCP(0x7eb856dd, 0x120e5c13),
+ WTCP(0x7eb0bb89, 0x12436f10), WTCP(0x7ea909fb, 0x12787ed8), WTCP(0x7ea14234, 0x12ad8b63),
+ WTCP(0x7e996435, 0x12e294a7), WTCP(0x7e916fff, 0x13179a9a), WTCP(0x7e896594, 0x134c9d34),
+ WTCP(0x7e8144f5, 0x13819c6b), WTCP(0x7e790e24, 0x13b69836), WTCP(0x7e70c123, 0x13eb908c),
+ WTCP(0x7e685df1, 0x14208562), WTCP(0x7e5fe492, 0x145576b1), WTCP(0x7e575507, 0x148a646e),
+ WTCP(0x7e4eaf50, 0x14bf4e91), WTCP(0x7e45f370, 0x14f43510), WTCP(0x7e3d2168, 0x152917e1),
+ WTCP(0x7e34393a, 0x155df6fc), WTCP(0x7e2b3ae7, 0x1592d257), WTCP(0x7e222671, 0x15c7a9ea),
+ WTCP(0x7e18fbd9, 0x15fc7da9), WTCP(0x7e0fbb21, 0x16314d8e), WTCP(0x7e06644b, 0x1666198d),
+ WTCP(0x7dfcf758, 0x169ae19f), WTCP(0x7df3744a, 0x16cfa5b9), WTCP(0x7de9db22, 0x170465d2),
+ WTCP(0x7de02be3, 0x173921e2), WTCP(0x7dd6668e, 0x176dd9de), WTCP(0x7dcc8b24, 0x17a28dbe),
+ WTCP(0x7dc299a8, 0x17d73d79), WTCP(0x7db8921b, 0x180be904), WTCP(0x7dae747f, 0x18409058),
+ WTCP(0x7da440d5, 0x1875336a), WTCP(0x7d99f720, 0x18a9d231), WTCP(0x7d8f9761, 0x18de6ca5),
+ WTCP(0x7d85219b, 0x191302bb), WTCP(0x7d7a95ce, 0x1947946c), WTCP(0x7d6ff3fd, 0x197c21ac),
+ WTCP(0x7d653c2a, 0x19b0aa75), WTCP(0x7d5a6e56, 0x19e52ebb), WTCP(0x7d4f8a84, 0x1a19ae76),
+ WTCP(0x7d4490b5, 0x1a4e299c), WTCP(0x7d3980eb, 0x1a82a025), WTCP(0x7d2e5b29, 0x1ab71208),
+ WTCP(0x7d231f6f, 0x1aeb7f3a), WTCP(0x7d17cdc1, 0x1b1fe7b3), WTCP(0x7d0c6620, 0x1b544b6a),
+ WTCP(0x7d00e88e, 0x1b88aa55), WTCP(0x7cf5550d, 0x1bbd046c), WTCP(0x7ce9aba0, 0x1bf159a4),
+ WTCP(0x7cddec47, 0x1c25a9f5), WTCP(0x7cd21706, 0x1c59f557), WTCP(0x7cc62bde, 0x1c8e3bbe),
+ WTCP(0x7cba2ad2, 0x1cc27d23), WTCP(0x7cae13e3, 0x1cf6b97c), WTCP(0x7ca1e714, 0x1d2af0c0),
+ WTCP(0x7c95a466, 0x1d5f22e6), WTCP(0x7c894bdd, 0x1d934fe5), WTCP(0x7c7cdd7a, 0x1dc777b3),
+ WTCP(0x7c70593f, 0x1dfb9a48), WTCP(0x7c63bf2e, 0x1e2fb79a), WTCP(0x7c570f4a, 0x1e63cfa0),
+ WTCP(0x7c4a4995, 0x1e97e251), WTCP(0x7c3d6e12, 0x1ecbefa3), WTCP(0x7c307cc1, 0x1efff78f),
+ WTCP(0x7c2375a7, 0x1f33fa0a), WTCP(0x7c1658c4, 0x1f67f70b), WTCP(0x7c09261c, 0x1f9bee8a),
+ WTCP(0x7bfbddb0, 0x1fcfe07d), WTCP(0x7bee7f84, 0x2003ccdb), WTCP(0x7be10b98, 0x2037b39b),
+ WTCP(0x7bd381f0, 0x206b94b4), WTCP(0x7bc5e28f, 0x209f701c), WTCP(0x7bb82d75, 0x20d345cb),
+ WTCP(0x7baa62a7, 0x210715b8), WTCP(0x7b9c8225, 0x213adfda), WTCP(0x7b8e8bf4, 0x216ea426),
+ WTCP(0x7b808014, 0x21a26295), WTCP(0x7b725e89, 0x21d61b1d), WTCP(0x7b642755, 0x2209cdb6),
+ WTCP(0x7b55da7b, 0x223d7a55), WTCP(0x7b4777fd, 0x227120f3), WTCP(0x7b38ffdd, 0x22a4c185),
+ WTCP(0x7b2a721e, 0x22d85c03), WTCP(0x7b1bcec3, 0x230bf064), WTCP(0x7b0d15cf, 0x233f7e9f),
+ WTCP(0x7afe4743, 0x237306ab), WTCP(0x7aef6323, 0x23a6887e), WTCP(0x7ae06970, 0x23da0410),
+ WTCP(0x7ad15a2f, 0x240d7958), WTCP(0x7ac23560, 0x2440e84c), WTCP(0x7ab2fb08, 0x247450e4),
+ WTCP(0x7aa3ab28, 0x24a7b316), WTCP(0x7a9445c4, 0x24db0eda), WTCP(0x7a84cadd, 0x250e6427),
+ WTCP(0x7a753a78, 0x2541b2f3), WTCP(0x7a659495, 0x2574fb35), WTCP(0x7a55d939, 0x25a83ce5),
+ WTCP(0x7a460867, 0x25db77fa), WTCP(0x7a36221f, 0x260eac6a), WTCP(0x7a262667, 0x2641da2c),
+ WTCP(0x7a16153f, 0x26750139), WTCP(0x7a05eeac, 0x26a82185), WTCP(0x79f5b2b0, 0x26db3b0a),
+ WTCP(0x79e5614e, 0x270e4dbd), WTCP(0x79d4fa88, 0x27415996), WTCP(0x79c47e62, 0x27745e8b),
+ WTCP(0x79b3ecdf, 0x27a75c95), WTCP(0x79a34601, 0x27da53a9), WTCP(0x799289cb, 0x280d43bf),
+ WTCP(0x7981b841, 0x28402cce), WTCP(0x7970d164, 0x28730ecd), WTCP(0x795fd539, 0x28a5e9b3),
+ WTCP(0x794ec3c2, 0x28d8bd78), WTCP(0x793d9d02, 0x290b8a11), WTCP(0x792c60fd, 0x293e4f77),
+ WTCP(0x791b0fb4, 0x29710da1), WTCP(0x7909a92c, 0x29a3c485), WTCP(0x78f82d67, 0x29d6741a),
+ WTCP(0x78e69c68, 0x2a091c59), WTCP(0x78d4f633, 0x2a3bbd37), WTCP(0x78c33aca, 0x2a6e56ac),
+ WTCP(0x78b16a31, 0x2aa0e8af), WTCP(0x789f846a, 0x2ad37338), WTCP(0x788d897a, 0x2b05f63d),
+ WTCP(0x787b7963, 0x2b3871b5), WTCP(0x78695427, 0x2b6ae598), WTCP(0x785719cb, 0x2b9d51dd),
+ WTCP(0x7844ca52, 0x2bcfb67b), WTCP(0x783265bf, 0x2c021368), WTCP(0x781fec14, 0x2c34689e),
+ WTCP(0x780d5d56, 0x2c66b611), WTCP(0x77fab988, 0x2c98fbba), WTCP(0x77e800ac, 0x2ccb3990),
+ WTCP(0x77d532c6, 0x2cfd6f8a), WTCP(0x77c24fda, 0x2d2f9d9f), WTCP(0x77af57eb, 0x2d61c3c6),
+ WTCP(0x779c4afb, 0x2d93e1f7), WTCP(0x7789290f, 0x2dc5f829), WTCP(0x7775f229, 0x2df80653),
+ WTCP(0x7762a64e, 0x2e2a0c6b), WTCP(0x774f4580, 0x2e5c0a6b), WTCP(0x773bcfc3, 0x2e8e0047),
+ WTCP(0x7728451b, 0x2ebfedf9), WTCP(0x7714a58a, 0x2ef1d377), WTCP(0x7700f114, 0x2f23b0b8),
+ WTCP(0x76ed27bd, 0x2f5585b4), WTCP(0x76d94988, 0x2f875262), WTCP(0x76c55679, 0x2fb916b9),
+ WTCP(0x76b14e92, 0x2fead2b0), WTCP(0x769d31d9, 0x301c863f), WTCP(0x7689004f, 0x304e315d),
+ WTCP(0x7674b9f9, 0x307fd401), WTCP(0x76605eda, 0x30b16e22), WTCP(0x764beef7, 0x30e2ffb9),
+ WTCP(0x76376a51, 0x311488bb), WTCP(0x7622d0ee, 0x31460921), WTCP(0x760e22d0, 0x317780e2),
+ WTCP(0x75f95ffb, 0x31a8eff5), WTCP(0x75e48874, 0x31da5651), WTCP(0x75cf9c3c, 0x320bb3ee),
+ WTCP(0x75ba9b59, 0x323d08c3), WTCP(0x75a585ce, 0x326e54c7), WTCP(0x75905b9f, 0x329f97f2),
+ WTCP(0x757b1ccf, 0x32d0d23b), WTCP(0x7565c961, 0x3302039a), WTCP(0x7550615b, 0x33332c06),
+ WTCP(0x753ae4bf, 0x33644b76), WTCP(0x75255392, 0x339561e1), WTCP(0x750fadd6, 0x33c66f3f),
+ WTCP(0x74f9f390, 0x33f77388), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74ce4176, 0x345960b6),
+ WTCP(0x74b849a9, 0x348a498b), WTCP(0x74a23d61, 0x34bb2927), WTCP(0x748c1ca3, 0x34ebff83),
+ WTCP(0x7475e771, 0x351ccc95), WTCP(0x745f9dd0, 0x354d9056), WTCP(0x74493fc4, 0x357e4abd),
+ WTCP(0x7432cd51, 0x35aefbc1), WTCP(0x741c467a, 0x35dfa35a), WTCP(0x7405ab44, 0x3610417e),
+ WTCP(0x73eefbb2, 0x3640d627), WTCP(0x73d837c9, 0x3671614a), WTCP(0x73c15f8c, 0x36a1e2e0),
+ WTCP(0x73aa7300, 0x36d25ae0), WTCP(0x73937229, 0x3702c942), WTCP(0x737c5d0a, 0x37332dfc),
+ WTCP(0x736533a8, 0x37638907), WTCP(0x734df606, 0x3793da5a), WTCP(0x7336a42a, 0x37c421ed),
+ WTCP(0x731f3e16, 0x37f45fb7), WTCP(0x7307c3cf, 0x382493b0), WTCP(0x72f03559, 0x3854bdce),
+ WTCP(0x72d892b9, 0x3884de0b), WTCP(0x72c0dbf2, 0x38b4f45d), WTCP(0x72a91108, 0x38e500bb),
+ WTCP(0x72913200, 0x3915031e), WTCP(0x72793edf, 0x3944fb7d), WTCP(0x726137a7, 0x3974e9d0),
+ WTCP(0x72491c5d, 0x39a4ce0e), WTCP(0x7230ed06, 0x39d4a82e), WTCP(0x7218a9a6, 0x3a047829),
+ WTCP(0x72005241, 0x3a343df6), WTCP(0x71e7e6db, 0x3a63f98d), WTCP(0x71cf6779, 0x3a93aae5),
+ WTCP(0x71b6d41f, 0x3ac351f5), WTCP(0x719e2cd1, 0x3af2eeb7), WTCP(0x71857194, 0x3b228120),
+ WTCP(0x716ca26b, 0x3b520929), WTCP(0x7153bf5c, 0x3b8186ca), WTCP(0x713ac86a, 0x3bb0f9f9),
+ WTCP(0x7121bd9b, 0x3be062b0), WTCP(0x71089ef1, 0x3c0fc0e5), WTCP(0x70ef6c73, 0x3c3f1490),
+ WTCP(0x70d62624, 0x3c6e5da9), WTCP(0x70bccc08, 0x3c9d9c28), WTCP(0x70a35e25, 0x3cccd004),
+ WTCP(0x7089dc7e, 0x3cfbf935), WTCP(0x70704718, 0x3d2b17b3), WTCP(0x70569df7, 0x3d5a2b75),
+ WTCP(0x703ce121, 0x3d893473), WTCP(0x70231099, 0x3db832a5), WTCP(0x70092c64, 0x3de72603),
+ WTCP(0x6fef3487, 0x3e160e85), WTCP(0x6fd52906, 0x3e44ec22), WTCP(0x6fbb09e6, 0x3e73bed1),
+ WTCP(0x6fa0d72b, 0x3ea2868c), WTCP(0x6f8690da, 0x3ed14349), WTCP(0x6f6c36f7, 0x3efff500),
+ WTCP(0x6f51c988, 0x3f2e9baa), WTCP(0x6f374890, 0x3f5d373e), WTCP(0x6f1cb415, 0x3f8bc7b3),
+ WTCP(0x6f020c1b, 0x3fba4d02), WTCP(0x6ee750a7, 0x3fe8c723), WTCP(0x6ecc81bd, 0x4017360d),
+ WTCP(0x6eb19f63, 0x404599b8), WTCP(0x6e96a99c, 0x4073f21d), WTCP(0x6e7ba06e, 0x40a23f32),
+ WTCP(0x6e6083dd, 0x40d080f0), WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6e2a10a7, 0x412ce246),
+ WTCP(0x6e0eba0b, 0x415b01ce), WTCP(0x6df3501f, 0x418915de), WTCP(0x6dd7d2e9, 0x41b71e6e),
+ WTCP(0x6dbc426d, 0x41e51b77), WTCP(0x6da09eb0, 0x42130cf0), WTCP(0x6d84e7b6, 0x4240f2d1),
+ WTCP(0x6d691d86, 0x426ecd12), WTCP(0x6d4d4022, 0x429c9baa), WTCP(0x6d314f92, 0x42ca5e93),
+ WTCP(0x6d154bd8, 0x42f815c4), WTCP(0x6cf934fb, 0x4325c135), WTCP(0x6cdd0aff, 0x435360de),
+ WTCP(0x6cc0cde9, 0x4380f4b6), WTCP(0x6ca47dbe, 0x43ae7cb6), WTCP(0x6c881a83, 0x43dbf8d7),
+ WTCP(0x6c6ba43d, 0x4409690f), WTCP(0x6c4f1af2, 0x4436cd57), WTCP(0x6c327ea5, 0x446425a7),
+ WTCP(0x6c15cf5c, 0x449171f7), WTCP(0x6bf90d1c, 0x44beb240), WTCP(0x6bdc37eb, 0x44ebe678),
+ WTCP(0x6bbf4fcc, 0x45190e99), WTCP(0x6ba254c6, 0x45462a9a), WTCP(0x6b8546dd, 0x45733a73),
+ WTCP(0x6b682617, 0x45a03e1d), WTCP(0x6b4af278, 0x45cd358f), WTCP(0x6b2dac05, 0x45fa20c2),
+ WTCP(0x6b1052c5, 0x4626ffae), WTCP(0x6af2e6bb, 0x4653d24a), WTCP(0x6ad567ee, 0x46809890),
+ WTCP(0x6ab7d662, 0x46ad5277), WTCP(0x6a9a321c, 0x46d9fff7), WTCP(0x6a7c7b22, 0x4706a109),
+ WTCP(0x6a5eb179, 0x473335a5), WTCP(0x6a40d526, 0x475fbdc2), WTCP(0x6a22e62f, 0x478c3959),
+ WTCP(0x6a04e498, 0x47b8a863), WTCP(0x69e6d067, 0x47e50ad7), WTCP(0x69c8a9a1, 0x481160ae),
+ WTCP(0x69aa704b, 0x483da9e0), WTCP(0x698c246b, 0x4869e664), WTCP(0x696dc606, 0x48961634),
+ WTCP(0x694f5522, 0x48c23948), WTCP(0x6930d1c3, 0x48ee4f98), WTCP(0x69123bf0, 0x491a591b),
+ WTCP(0x68f393ad, 0x494655cb), WTCP(0x68d4d8ff, 0x497245a0), WTCP(0x68b60bed, 0x499e2892),
+ WTCP(0x68972c7c, 0x49c9fe99), WTCP(0x68783ab1, 0x49f5c7ad), WTCP(0x68593691, 0x4a2183c7),
+ WTCP(0x683a2022, 0x4a4d32e0), WTCP(0x681af769, 0x4a78d4ef), WTCP(0x67fbbc6c, 0x4aa469ed),
+ WTCP(0x67dc6f31, 0x4acff1d2), WTCP(0x67bd0fbc, 0x4afb6c97), WTCP(0x679d9e13, 0x4b26da34),
+ WTCP(0x677e1a3d, 0x4b523aa1), WTCP(0x675e843e, 0x4b7d8dd7), WTCP(0x673edc1b, 0x4ba8d3cf),
+ WTCP(0x671f21db, 0x4bd40c7f), WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x66df7719, 0x4c2a55ef),
+ WTCP(0x66bf86a2, 0x4c55669f), WTCP(0x669f8424, 0x4c8069ea), WTCP(0x667f6fa4, 0x4cab5fc9),
+ WTCP(0x665f4928, 0x4cd64834), WTCP(0x663f10b6, 0x4d012324), WTCP(0x661ec653, 0x4d2bf090),
+ WTCP(0x65fe6a05, 0x4d56b073), WTCP(0x65ddfbd2, 0x4d8162c3), WTCP(0x65bd7bc0, 0x4dac077b),
+ WTCP(0x659ce9d3, 0x4dd69e91), WTCP(0x657c4612, 0x4e0127ff), WTCP(0x655b9083, 0x4e2ba3be),
+ WTCP(0x653ac92a, 0x4e5611c5), WTCP(0x6519f00f, 0x4e80720d), WTCP(0x64f90537, 0x4eaac48f),
+ WTCP(0x64d808a7, 0x4ed50944), WTCP(0x64b6fa65, 0x4eff4024), WTCP(0x6495da78, 0x4f296927),
+ WTCP(0x6474a8e5, 0x4f538447), WTCP(0x645365b1, 0x4f7d917c), WTCP(0x643210e3, 0x4fa790be),
+ WTCP(0x6410aa80, 0x4fd18206), WTCP(0x63ef328f, 0x4ffb654c), WTCP(0x63cda915, 0x50253a8b),
+ WTCP(0x63ac0e18, 0x504f01b9), WTCP(0x638a619e, 0x5078bad0), WTCP(0x6368a3ac, 0x50a265c8),
+ WTCP(0x6346d44a, 0x50cc029b), WTCP(0x6324f37c, 0x50f59140), WTCP(0x63030149, 0x511f11b1),
+ WTCP(0x62e0fdb7, 0x514883e6), WTCP(0x62bee8cb, 0x5171e7d8), WTCP(0x629cc28c, 0x519b3d80),
+ WTCP(0x627a8aff, 0x51c484d6), WTCP(0x6258422b, 0x51edbdd3), WTCP(0x6235e815, 0x5216e870),
+ WTCP(0x62137cc4, 0x524004a6), WTCP(0x61f1003e, 0x5269126e), WTCP(0x61ce7289, 0x529211c0),
+ WTCP(0x61abd3aa, 0x52bb0295), WTCP(0x618923a8, 0x52e3e4e5), WTCP(0x61666289, 0x530cb8ab),
+ WTCP(0x61439053, 0x53357dde), WTCP(0x6120ad0c, 0x535e3478), WTCP(0x60fdb8ba, 0x5386dc71),
+ WTCP(0x60dab364, 0x53af75c2), WTCP(0x60b79d0f, 0x53d80064), WTCP(0x609475c2, 0x54007c50),
+ WTCP(0x60713d83, 0x5428e97f), WTCP(0x604df458, 0x545147ea), WTCP(0x602a9a47, 0x54799789),
+ WTCP(0x60072f56, 0x54a1d856), WTCP(0x5fe3b38d, 0x54ca0a4a), WTCP(0x5fc026f0, 0x54f22d5d),
+ WTCP(0x5f9c8986, 0x551a4188), WTCP(0x5f78db55, 0x554246c5), WTCP(0x5f551c64, 0x556a3d0c),
+ WTCP(0x5f314cb9, 0x55922457), WTCP(0x5f0d6c5b, 0x55b9fc9d), WTCP(0x5ee97b4e, 0x55e1c5da),
+ WTCP(0x5ec5799b, 0x56098004), WTCP(0x5ea16746, 0x56312b16), WTCP(0x5e7d4457, 0x5658c709),
+ WTCP(0x5e5910d4, 0x568053d5), WTCP(0x5e34ccc3, 0x56a7d173), WTCP(0x5e10782a, 0x56cf3fdd),
+ WTCP(0x5dec1310, 0x56f69f0c), WTCP(0x5dc79d7b, 0x571deef9), WTCP(0x5da31772, 0x57452f9d),
+ WTCP(0x5d7e80fb, 0x576c60f0), WTCP(0x5d59da1d, 0x579382ed), WTCP(0x5d3522dd, 0x57ba958c),
+ WTCP(0x5d105b43, 0x57e198c6), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5cc69b18, 0x582f70f2),
+ WTCP(0x5ca1a295, 0x585645d6), WTCP(0x5c7c99d0, 0x587d0b3a), WTCP(0x5c5780d2, 0x58a3c117),
+ WTCP(0x5c3257a0, 0x58ca6767), WTCP(0x5c0d1e40, 0x58f0fe22), WTCP(0x5be7d4ba, 0x59178542),
+ WTCP(0x5bc27b13, 0x593dfcc1), WTCP(0x5b9d1153, 0x59646497), WTCP(0x5b779780, 0x598abcbe),
+ WTCP(0x5b520da0, 0x59b1052e), WTCP(0x5b2c73ba, 0x59d73de2), WTCP(0x5b06c9d6, 0x59fd66d3),
+ WTCP(0x5ae10ff8, 0x5a237ff9), WTCP(0x5abb4628, 0x5a49894f), WTCP(0x5a956c6d, 0x5a6f82cd),
+};
+# endif
+
+// fs 48 32 24 16 8
+// ms +--------------------
+// 10.0 | 480 320 240 160 80
+// 7.5 | 360 240 180 120 60
+// 5.0 | 240 160 120 80 40
+// 2.5 | 120 80 60 40 20
+
+void BASOP_getTables(
+#ifdef ENABLE_HR_MODE
+ const PWord32 **twiddle, const PWord32 **sin,
+#else
+ const PWord16 **twiddle, const PWord16 **sin,
+#endif
+ Word16 *sin_step, Word16 length)
+{
+ SWITCH (length)
+ {
+ case 20:
+ *sin = SineTable320;
+ move16();
+ *sin_step = 32;
+ move16();
+ *twiddle = SineWindow20;
+ move16();
+ BREAK;
+ case 40:
+ *sin = SineTable320;
+ move16();
+ *sin_step = 16;
+ move16();
+ *twiddle = SineWindow40;
+ move16();
+ BREAK;
+ case 60:
+ *sin = SineTable480;
+ move16();
+ *sin_step = 16;
+ move16();
+ *twiddle = SineWindow60;
+ move16();
+ BREAK;
+ case 80:
+ *sin = SineTable320;
+ move16();
+ *sin_step = 8;
+ move16();
+ *twiddle = SineWindow80;
+ move16();
+ BREAK;
+ case 120:
+ *sin = SineTable480;
+ move16();
+ *sin_step = 8;
+ move16();
+ *twiddle = SineWindow120;
+ move16();
+ BREAK;
+ case 160:
+ *sin = SineTable320;
+ move16();
+ *sin_step = 4;
+ move16();
+ *twiddle = SineWindow160;
+ move16();
+ BREAK;
+ case 180:
+ *sin = SineTable360;
+ move16();
+ *sin_step = 4;
+ move16();
+ *twiddle = SineWindow180;
+ move16();
+ BREAK;
+ case 240:
+ *sin = SineTable480;
+ move16();
+ *sin_step = 4;
+ move16();
+ *twiddle = SineWindow240;
+ move16();
+ BREAK;
+ case 320:
+ *sin = SineTable320;
+ move16();
+ *sin_step = 2;
+ move16();
+ *twiddle = SineWindow320;
+ move16();
+ BREAK;
+ case 360:
+ *sin = SineTable360;
+ move16();
+ *sin_step = 2;
+ move16();
+ *twiddle = SineWindow360;
+ move16();
+ BREAK;
+ case 480:
+ *sin = SineTable480;
+ move16();
+ *sin_step = 2;
+ move16();
+ *twiddle = SineWindow480;
+ move16();
+ BREAK;
+#ifdef ENABLE_HR_MODE
+# ifdef CR8_G_ADD_75MS
+ case 720:
+ *sin = SineTable720;
+ move16();
+ *sin_step = 2;
+ move16();
+ *twiddle = SineWindow720;
+ move16();
+ break;
+# endif
+ case 960:
+ *sin = SineTable960;
+ move16();
+ *sin_step = 2;
+ move16();
+ *twiddle = SineWindow960;
+ move16();
+ break;
+#endif
+ default: ASSERT(0);
+ }
+}
+
+const Word32 RealFFT32_twid[10] = {
+ 0x7fffffff, 0x00000000, 0x7d8a5f40, 0x18f8b83c, 0x7641af3d,
+ 0x30fbc54d, 0x6a6d98a4, 0x471cece7, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT40_twid[12] = {
+ 0x7fffffff, 0x00000000, 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e,
+ 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT64_twid[18] = {
+ 0x7fffffff, 0x00000000, 0x7f62368f, 0x0c8bd35e, 0x7d8a5f40, 0x18f8b83c, 0x7a7d055b, 0x25280c5e, 0x7641af3d,
+ 0x30fbc54d, 0x70e2cbc6, 0x3c56ba70, 0x6a6d98a4, 0x471cece7, 0x62f201ac, 0x5133cc94, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT80_twid[22] = {
+ 0x7fffffff, 0x00000000, 0x7f9afcb9, 0x0a0af299, 0x7e6c9251, 0x14060b68, 0x7c769e18, 0x1de189a6,
+ 0x79bc384d, 0x278dde6e, 0x7641af3d, 0x30fbc54d, 0x720c8075, 0x3a1c5c57, 0x6d23501b, 0x42e13ba4,
+ 0x678dde6e, 0x4b3c8c12, 0x6154fb91, 0x53211d18, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT96_twid[26] = {
+ 0x7fffffff, 0x00000000, 0x7fb9d759, 0x085f2137, 0x7ee7aa4c, 0x10b5150f, 0x7d8a5f40, 0x18f8b83c, 0x7ba3751d,
+ 0x2120fb83, 0x793501a9, 0x2924edac, 0x7641af3d, 0x30fbc54d, 0x72ccb9db, 0x389cea72, 0x6ed9eba1, 0x40000000,
+ 0x6a6d98a4, 0x471cece7, 0x658c9a2d, 0x4debe4fe, 0x603c496c, 0x54657194, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT128_twid[34] = {
+ 0x7fffffff, 0x00000000, 0x7fd8878e, 0x0647d97c, 0x7f62368f, 0x0c8bd35e, 0x7e9d55fc, 0x12c8106f, 0x7d8a5f40,
+ 0x18f8b83c, 0x7c29fbee, 0x1f19f97b, 0x7a7d055b, 0x25280c5e, 0x78848414, 0x2b1f34eb, 0x7641af3d, 0x30fbc54d,
+ 0x73b5ebd1, 0x36ba2014, 0x70e2cbc6, 0x3c56ba70, 0x6dca0d14, 0x41ce1e65, 0x6a6d98a4, 0x471cece7, 0x66cf8120,
+ 0x4c3fdff4, 0x62f201ac, 0x5133cc94, 0x5ed77c8a, 0x55f5a4d2, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT192_twid[50] = {
+ 0x7fffffff, 0x00000000, 0x7fee74a2, 0x0430238f, 0x7fb9d759, 0x085f2137, 0x7f62368f, 0x0c8bd35e, 0x7ee7aa4c,
+ 0x10b5150f, 0x7e4a5426, 0x14d9c245, 0x7d8a5f40, 0x18f8b83c, 0x7ca80038, 0x1d10d5c2, 0x7ba3751d, 0x2120fb83,
+ 0x7a7d055b, 0x25280c5e, 0x793501a9, 0x2924edac, 0x77cbc3f2, 0x2d168792, 0x7641af3d, 0x30fbc54d, 0x74972f92,
+ 0x34d3957e, 0x72ccb9db, 0x389cea72, 0x70e2cbc6, 0x3c56ba70, 0x6ed9eba1, 0x40000000, 0x6cb2a837, 0x4397ba32,
+ 0x6a6d98a4, 0x471cece7, 0x680b5c33, 0x4a8ea111, 0x658c9a2d, 0x4debe4fe, 0x62f201ac, 0x5133cc94, 0x603c496c,
+ 0x54657194, 0x5d6c2f99, 0x577ff3da, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT256_twid[66] = {
+ 0x7fffffff, 0x00000000, 0x7ff62182, 0x03242abf, 0x7fd8878e, 0x0647d97c, 0x7fa736b4, 0x096a9049, 0x7f62368f,
+ 0x0c8bd35e, 0x7f0991c4, 0x0fab272b, 0x7e9d55fc, 0x12c8106f, 0x7e1d93ea, 0x15e21445, 0x7d8a5f40, 0x18f8b83c,
+ 0x7ce3ceb2, 0x1c0b826a, 0x7c29fbee, 0x1f19f97b, 0x7b5d039e, 0x2223a4c5, 0x7a7d055b, 0x25280c5e, 0x798a23b1,
+ 0x2826b928, 0x78848414, 0x2b1f34eb, 0x776c4edb, 0x2e110a62, 0x7641af3d, 0x30fbc54d, 0x7504d345, 0x33def287,
+ 0x73b5ebd1, 0x36ba2014, 0x72552c85, 0x398cdd32, 0x70e2cbc6, 0x3c56ba70, 0x6f5f02b2, 0x3f1749b8, 0x6dca0d14,
+ 0x41ce1e65, 0x6c242960, 0x447acd50, 0x6a6d98a4, 0x471cece7, 0x68a69e81, 0x49b41533, 0x66cf8120, 0x4c3fdff4,
+ 0x64e88926, 0x4ebfe8a5, 0x62f201ac, 0x5133cc94, 0x60ec3830, 0x539b2af0, 0x5ed77c8a, 0x55f5a4d2, 0x5cb420e0,
+ 0x5842dd54, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT384_twid[98] = {
+ 0x7fffffff, 0x00000000, 0x7ffb9d15, 0x02182427, 0x7fee74a2, 0x0430238f, 0x7fd8878e, 0x0647d97c, 0x7fb9d759,
+ 0x085f2137, 0x7f92661d, 0x0a75d60e, 0x7f62368f, 0x0c8bd35e, 0x7f294bfd, 0x0ea0f48c, 0x7ee7aa4c, 0x10b5150f,
+ 0x7e9d55fc, 0x12c8106f, 0x7e4a5426, 0x14d9c245, 0x7deeaa7a, 0x16ea0646, 0x7d8a5f40, 0x18f8b83c, 0x7d1d7958,
+ 0x1b05b40f, 0x7ca80038, 0x1d10d5c2, 0x7c29fbee, 0x1f19f97b, 0x7ba3751d, 0x2120fb83, 0x7b1474fd, 0x2325b847,
+ 0x7a7d055b, 0x25280c5e, 0x79dd3098, 0x2727d486, 0x793501a9, 0x2924edac, 0x78848414, 0x2b1f34eb, 0x77cbc3f2,
+ 0x2d168792, 0x770acdec, 0x2f0ac320, 0x7641af3d, 0x30fbc54d, 0x757075ac, 0x32e96c09, 0x74972f92, 0x34d3957e,
+ 0x73b5ebd1, 0x36ba2014, 0x72ccb9db, 0x389cea72, 0x71dba9ab, 0x3a7bd382, 0x70e2cbc6, 0x3c56ba70, 0x6fe2313c,
+ 0x3e2d7eb1, 0x6ed9eba1, 0x40000000, 0x6dca0d14, 0x41ce1e65, 0x6cb2a837, 0x4397ba32, 0x6b93d02e, 0x455cb40c,
+ 0x6a6d98a4, 0x471cece7, 0x694015c3, 0x48d84609, 0x680b5c33, 0x4a8ea111, 0x66cf8120, 0x4c3fdff4, 0x658c9a2d,
+ 0x4debe4fe, 0x6442bd7e, 0x4f9292dc, 0x62f201ac, 0x5133cc94, 0x619a7dce, 0x52cf758f, 0x603c496c, 0x54657194,
+ 0x5ed77c8a, 0x55f5a4d2, 0x5d6c2f99, 0x577ff3da, 0x5bfa7b82, 0x590443a7, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT512_twid[130] = {
+ 0x7fffffff, 0x00000000, 0x7ffd885a, 0x01921d20, 0x7ff62182, 0x03242abf, 0x7fe9cbc0, 0x04b6195d, 0x7fd8878e,
+ 0x0647d97c, 0x7fc25596, 0x07d95b9e, 0x7fa736b4, 0x096a9049, 0x7f872bf3, 0x0afb6805, 0x7f62368f, 0x0c8bd35e,
+ 0x7f3857f6, 0x0e1bc2e4, 0x7f0991c4, 0x0fab272b, 0x7ed5e5c6, 0x1139f0cf, 0x7e9d55fc, 0x12c8106f, 0x7e5fe493,
+ 0x145576b1, 0x7e1d93ea, 0x15e21445, 0x7dd6668f, 0x176dd9de, 0x7d8a5f40, 0x18f8b83c, 0x7d3980ec, 0x1a82a026,
+ 0x7ce3ceb2, 0x1c0b826a, 0x7c894bde, 0x1d934fe5, 0x7c29fbee, 0x1f19f97b, 0x7bc5e290, 0x209f701c, 0x7b5d039e,
+ 0x2223a4c5, 0x7aef6323, 0x23a6887f, 0x7a7d055b, 0x25280c5e, 0x7a05eead, 0x26a82186, 0x798a23b1, 0x2826b928,
+ 0x7909a92d, 0x29a3c485, 0x78848414, 0x2b1f34eb, 0x77fab989, 0x2c98fbba, 0x776c4edb, 0x2e110a62, 0x76d94989,
+ 0x2f875262, 0x7641af3d, 0x30fbc54d, 0x75a585cf, 0x326e54c7, 0x7504d345, 0x33def287, 0x745f9dd1, 0x354d9057,
+ 0x73b5ebd1, 0x36ba2014, 0x7307c3d0, 0x382493b0, 0x72552c85, 0x398cdd32, 0x719e2cd2, 0x3af2eeb7, 0x70e2cbc6,
+ 0x3c56ba70, 0x7023109a, 0x3db832a6, 0x6f5f02b2, 0x3f1749b8, 0x6e96a99d, 0x4073f21d, 0x6dca0d14, 0x41ce1e65,
+ 0x6cf934fc, 0x4325c135, 0x6c242960, 0x447acd50, 0x6b4af279, 0x45cd358f, 0x6a6d98a4, 0x471cece7, 0x698c246c,
+ 0x4869e665, 0x68a69e81, 0x49b41533, 0x67bd0fbd, 0x4afb6c98, 0x66cf8120, 0x4c3fdff4, 0x65ddfbd3, 0x4d8162c4,
+ 0x64e88926, 0x4ebfe8a5, 0x63ef3290, 0x4ffb654d, 0x62f201ac, 0x5133cc94, 0x61f1003f, 0x5269126e, 0x60ec3830,
+ 0x539b2af0, 0x5fe3b38d, 0x54ca0a4b, 0x5ed77c8a, 0x55f5a4d2, 0x5dc79d7c, 0x571deefa, 0x5cb420e0, 0x5842dd54,
+ 0x5b9d1154, 0x59646498, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RealFFT768_twid[194] = {
+ 0x7fffffff, 0x00000000, 0x7ffee744, 0x010c1460, 0x7ffb9d15, 0x02182427, 0x7ff62182, 0x03242abf, 0x7fee74a2,
+ 0x0430238f, 0x7fe49698, 0x053c0a01, 0x7fd8878e, 0x0647d97c, 0x7fca47b9, 0x07538d6b, 0x7fb9d759, 0x085f2137,
+ 0x7fa736b4, 0x096a9049, 0x7f92661d, 0x0a75d60e, 0x7f7b65ef, 0x0b80edf1, 0x7f62368f, 0x0c8bd35e, 0x7f46d86c,
+ 0x0d9681c2, 0x7f294bfd, 0x0ea0f48c, 0x7f0991c4, 0x0fab272b, 0x7ee7aa4c, 0x10b5150f, 0x7ec3962a, 0x11beb9aa,
+ 0x7e9d55fc, 0x12c8106f, 0x7e74ea6a, 0x13d114d0, 0x7e4a5426, 0x14d9c245, 0x7e1d93ea, 0x15e21445, 0x7deeaa7a,
+ 0x16ea0646, 0x7dbd98a4, 0x17f193c5, 0x7d8a5f40, 0x18f8b83c, 0x7d54ff2e, 0x19ff6f2a, 0x7d1d7958, 0x1b05b40f,
+ 0x7ce3ceb2, 0x1c0b826a, 0x7ca80038, 0x1d10d5c2, 0x7c6a0ef2, 0x1e15a99a, 0x7c29fbee, 0x1f19f97b, 0x7be7c847,
+ 0x201dc0ef, 0x7ba3751d, 0x2120fb83, 0x7b5d039e, 0x2223a4c5, 0x7b1474fd, 0x2325b847, 0x7ac9ca7a, 0x2427319d,
+ 0x7a7d055b, 0x25280c5e, 0x7a2e26f2, 0x26284422, 0x79dd3098, 0x2727d486, 0x798a23b1, 0x2826b928, 0x793501a9,
+ 0x2924edac, 0x78ddcbf5, 0x2a226db5, 0x78848414, 0x2b1f34eb, 0x78292b8d, 0x2c1b3efb, 0x77cbc3f2, 0x2d168792,
+ 0x776c4edb, 0x2e110a62, 0x770acdec, 0x2f0ac320, 0x76a742d1, 0x3003ad85, 0x7641af3d, 0x30fbc54d, 0x75da14ef,
+ 0x31f30638, 0x757075ac, 0x32e96c09, 0x7504d345, 0x33def287, 0x74972f92, 0x34d3957e, 0x74278c72, 0x35c750bc,
+ 0x73b5ebd1, 0x36ba2014, 0x73424fa0, 0x37abff5d, 0x72ccb9db, 0x389cea72, 0x72552c85, 0x398cdd32, 0x71dba9ab,
+ 0x3a7bd382, 0x71603361, 0x3b69c947, 0x70e2cbc6, 0x3c56ba70, 0x706374ff, 0x3d42a2ec, 0x6fe2313c, 0x3e2d7eb1,
+ 0x6f5f02b2, 0x3f1749b8, 0x6ed9eba1, 0x40000000, 0x6e52ee52, 0x40e79d8c, 0x6dca0d14, 0x41ce1e65, 0x6d3f4a40,
+ 0x42b37e96, 0x6cb2a837, 0x4397ba32, 0x6c242960, 0x447acd50, 0x6b93d02e, 0x455cb40c, 0x6b019f1a, 0x463d6a87,
+ 0x6a6d98a4, 0x471cece7, 0x69d7bf57, 0x47fb3757, 0x694015c3, 0x48d84609, 0x68a69e81, 0x49b41533, 0x680b5c33,
+ 0x4a8ea111, 0x676e5183, 0x4b67e5e4, 0x66cf8120, 0x4c3fdff4, 0x662eedc3, 0x4d168b8b, 0x658c9a2d, 0x4debe4fe,
+ 0x64e88926, 0x4ebfe8a5, 0x6442bd7e, 0x4f9292dc, 0x639b3a0b, 0x5063e008, 0x62f201ac, 0x5133cc94, 0x62471749,
+ 0x520254ef, 0x619a7dce, 0x52cf758f, 0x60ec3830, 0x539b2af0, 0x603c496c, 0x54657194, 0x5f8ab487, 0x552e4605,
+ 0x5ed77c8a, 0x55f5a4d2, 0x5e22a487, 0x56bb8a90, 0x5d6c2f99, 0x577ff3da, 0x5cb420e0, 0x5842dd54, 0x5bfa7b82,
+ 0x590443a7, 0x5b3f42ae, 0x59c42381, 0x5a82799a, 0x5a82799a,
+};
+
+const Word32 RotVector_32_32[2 * 20] = {
+ 0x7d8a5f00, 0xe70747c0, 0x7641b000, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x5a827980, 0xa57d8680,
+ 0x471ced80, 0x95926780, 0x30fbc600, 0x89be5100, 0x18f8b800, 0x8275a100, 0x7641b000, 0xcf043ac0,
+ 0x5a827980, 0xa57d8680, 0x30fbc600, 0x89be5100, 0xcf043b00, 0x89be5100, 0xa57d8680, 0xa57d8680,
+ 0x89be5100, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x30fbc600, 0x89be5100, 0xe7074800, 0x8275a100,
+ 0xa57d8680, 0xa57d8680, 0x8275a100, 0xe70747c0, 0x89be5000, 0x30fbc540, 0xb8e31280, 0x6a6d9880,
+};
+
+const Word32 RotVector_40_32[2 * 28] = {
+ 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e, 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12,
+ 0x79bc384d, 0x278dde6e, 0x678dde6e, 0x4b3c8c12, 0x4b3c8c12, 0x678dde6e, 0x278dde6e, 0x79bc384d,
+ 0x720c8075, 0x3a1c5c57, 0x4b3c8c12, 0x678dde6e, 0x14060b68, 0x7e6c9251, 0xd8722192, 0x79bc384d,
+ 0x678dde6e, 0x4b3c8c12, 0x278dde6e, 0x79bc384d, 0xd8722192, 0x79bc384d, 0x98722192, 0x4b3c8c12,
+ 0x5a82799a, 0x5a82799a, 0x00000000, 0x7fffffff, 0xa57d8666, 0x5a82799a, 0x80000000, 0x00000000,
+ 0x4b3c8c12, 0x678dde6e, 0xd8722192, 0x79bc384d, 0x8643c7b3, 0x278dde6e, 0x98722192, 0xb4c373ee,
+ 0x3a1c5c57, 0x720c8075, 0xb4c373ee, 0x678dde6e, 0x81936daf, 0xebf9f498, 0xd8722192, 0x8643c7b3,
+};
+
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_480[2 * (480 - 30)] = {
+# else
+const Word16 RotVector_480[2 * (480 - 30)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e),
+ SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000),
+ SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443),
+ SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4),
+ SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8),
+ SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67),
+ SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd),
+ SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d),
+ SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a),
+ SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4),
+ SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e),
+ SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84),
+ SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83),
+ SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2),
+ SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6),
+ SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40),
+ SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d),
+ SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)};
+
+# ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+const Word32 RotVector_720[2 * (720 - 30)] = {
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce),
+ SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4),
+ SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d),
+ SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849),
+ SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce),
+ SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582),
+ SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7),
+ SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce),
+ SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d),
+ SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e),
+ SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b),
+ SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b),
+ SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7),
+ SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860),
+ SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17),
+ SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7),
+ SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e),
+ SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7),
+ SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9),
+ SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b),
+ SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32),
+ SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422),
+ SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c),
+ SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786),
+ SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b),
+ SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26),
+ SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49),
+ SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba),
+ SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d),
+ SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67),
+ SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd),
+ SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d),
+ SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a),
+ SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4),
+ SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e),
+ SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84),
+ SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83),
+ SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2),
+ SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6),
+ SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40),
+ SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d),
+ SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7),
+ SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff),
+ SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff),
+ SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0xfb887fec), SHC(0xf7127fb0),
+ SHC(0xf29f7f4c), SHC(0xee307ec1), SHC(0xe9c67e0e), SHC(0xe5637d34), SHC(0xe1097c33), SHC(0xdcb87b0b),
+ SHC(0xd87279bc), SHC(0xd4397848), SHC(0xd00d76ae), SHC(0xcbf074ef), SHC(0xc7e3730c), SHC(0xc3e87104),
+ SHC(0x00007fff), SHC(0xf7127fb0), SHC(0xee307ec1), SHC(0xe5637d34), SHC(0xdcb87b0b), SHC(0xd4397848),
+ SHC(0xcbf074ef), SHC(0xc3e87104), SHC(0xbc2c6c8d), SHC(0xb4c3678e), SHC(0xadb9620e), SHC(0xa7155c13),
+ SHC(0xa0e155a6), SHC(0x9b224ece), SHC(0x95e24794), SHC(0x00007fff), SHC(0xf29f7f4c), SHC(0xe5637d34),
+ SHC(0xd87279bc), SHC(0xcbf074ef), SHC(0xc0006eda), SHC(0xb4c3678e), SHC(0xaa5a5f1f), SHC(0xa0e155a6),
+ SHC(0x98724b3d), SHC(0x91264000), SHC(0x8b113410), SHC(0x8644278e), SHC(0x82cc1a9d), SHC(0x80b40d61),
+ SHC(0x00007fff), SHC(0xee307ec1), SHC(0xdcb87b0b), SHC(0xcbf074ef), SHC(0xbc2c6c8d), SHC(0xadb9620e),
+ SHC(0xa0e155a6), SHC(0x95e24794), SHC(0x8cf4381d), SHC(0x8644278e), SHC(0x81f2163a), SHC(0x80140478),
+ SHC(0x80b4f29f), SHC(0x83cde109), SHC(0x8952d00d), SHC(0x00007fff), SHC(0xe9c67e0e), SHC(0xd4397848),
+ SHC(0xc0006eda), SHC(0xadb9620e), SHC(0x9df25247), SHC(0x91264000), SHC(0x87b82bc7), SHC(0x81f2163a),
+ SHC(0x80000000), SHC(0x81f2e9c6), SHC(0x87b8d439), SHC(0x9126c000), SHC(0x9df2adb9), SHC(0xadb99df2),
+ SHC(0x00007fff), SHC(0xe5637d34), SHC(0xcbf074ef), SHC(0xb4c3678e), SHC(0xa0e155a6), SHC(0x91264000),
+ SHC(0x8644278e), SHC(0x80b40d61), SHC(0x80b4f29f), SHC(0x8644d872), SHC(0x9126c000), SHC(0xa0e1aa5a),
+ SHC(0xb4c39872), SHC(0xcbf08b11), SHC(0xe56382cc), SHC(0x00007fff), SHC(0xe1097c33), SHC(0xc3e87104),
+ SHC(0xaa5a5f1f), SHC(0x95e24794), SHC(0x87b82bc7), SHC(0x80b40d61), SHC(0x813fee30), SHC(0x8952d00d),
+ SHC(0x9872b4c3), SHC(0xadb99df2), SHC(0xc7e38cf4), SHC(0xe56382cc), SHC(0x04788014), SHC(0x234884f5),
+ SHC(0x00007fff), SHC(0xdcb87b0b), SHC(0xbc2c6c8d), SHC(0xa0e155a6), SHC(0x8cf4381d), SHC(0x81f2163a),
+ SHC(0x80b4f29f), SHC(0x8952d00d), SHC(0x9b22b132), SHC(0xb4c39872), SHC(0xd43987b8), SHC(0xf7128050),
+ SHC(0x1a9d82cc), SHC(0x3c188efc), SHC(0x58eba3ed), SHC(0x00007fff), SHC(0xd87279bc), SHC(0xb4c3678e),
+ SHC(0x98724b3d), SHC(0x8644278e), SHC(0x80000000), SHC(0x8644d872), SHC(0x9872b4c3), SHC(0xb4c39872),
+ SHC(0xd8728644), SHC(0x00008000), SHC(0x278e8644), SHC(0x4b3d9872), SHC(0x678eb4c3), SHC(0x79bcd872),
+ SHC(0x00007fff), SHC(0xd4397848), SHC(0xadb9620e), SHC(0x91264000), SHC(0x81f2163a), SHC(0x81f2e9c6),
+ SHC(0x9126c000), SHC(0xadb99df2), SHC(0xd43987b8), SHC(0x00008000), SHC(0x2bc787b8), SHC(0x52479df2),
+ SHC(0x6edac000), SHC(0x7e0ee9c6), SHC(0x7e0e163a), SHC(0x00007fff), SHC(0xd00d76ae), SHC(0xa7155c13),
+ SHC(0x8b113410), SHC(0x80140478), SHC(0x87b8d439), SHC(0xa0e1aa5a), SHC(0xc7e38cf4), SHC(0xf7128050),
+ SHC(0x278e8644), SHC(0x52479df2), SHC(0x7104c3e8), SHC(0x7f4cf29f), SHC(0x7b0b2348), SHC(0x64de4ece),
+ SHC(0x00007fff), SHC(0xe21e7c77), SHC(0xc5e4720d), SHC(0xacdf6155), SHC(0x98724b3d), SHC(0x89be30fc),
+ SHC(0x81931406), SHC(0x8065f5f5), SHC(0x8644d872), SHC(0x92ddbd1f), SHC(0xa57ea57e), SHC(0xbd1f92dd),
+ SHC(0xd8728644), SHC(0xf5f58065), SHC(0x14068193), SHC(0x00007fff), SHC(0xdba57abb), SHC(0xba496b5a),
+ SHC(0x9eab5321), SHC(0x8b113410), SHC(0x811810b5), SHC(0x8193ebfa), SHC(0x8c78c8e5), SHC(0xa0e1aa5a),
+ SHC(0xbd1f92dd), SHC(0xdedf845d), SHC(0x035a800b), SHC(0x278e8644), SHC(0x48809683), SHC(0x637aaf72),
+ SHC(0x00007fff), SHC(0xd54678a8), SHC(0xaf72637a), SHC(0x92dd42e1), SHC(0x82cc1a9d), SHC(0x8118ef4b),
+ SHC(0x8df3c5e4), SHC(0xa7e4a327), SHC(0xcbf08b11), SHC(0xf5f58065), SHC(0x2121845d), SHC(0x48809683),
+ SHC(0x678eb4c3), SHC(0x7abbdba5), SHC(0x7fd306b3), SHC(0x00007fff), SHC(0xcf047642), SHC(0xa57e5a82),
+ SHC(0x89be30fc), SHC(0x80000000), SHC(0x89becf04), SHC(0xa57ea57e), SHC(0xcf0489be), SHC(0x00008000),
+ SHC(0x30fc89be), SHC(0x5a82a57e), SHC(0x7642cf04), SHC(0x7fff0000), SHC(0x764230fc), SHC(0x5a825a82),
+ SHC(0xe2e1004b), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb076e0), SHC(0x002fba9c), SHC(0x6fb079d0),
+ SHC(0x8d92be50), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff),
+ SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xeabee318), SHC(0x00000000), SHC(0x4d55545a),
+ SHC(0000000000), SHC(0000000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x904f882f),
+ SHC(0x4d55545a), SHC(0x00000000), SHC(0x00000000), SHC(0x006f5dd8), SHC(0x40000000), SHC(0x00666004),
+ SHC(0x006ec0b0), SHC(0x00660000), SHC(0x006f5dd8), SHC(0x42000000), SHC(0x00665fa0), SHC(0x006ec080),
+ SHC(0x6fb07880), SHC(0x00660000), SHC(0x00660000), SHC(0x00309ca0), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x0d888000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000),
+ SHC(0x00000170), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb07880), SHC(0x6fb078a8), SHC(0x8d926000),
+ SHC(0x0d888000), SHC(0x8d888000), SHC(0x6fb079e0), SHC(0x00000000), SHC(0000000000), SHC(0x002f8000),
+ SHC(0x00000001), SHC(0x6fb07b40), SHC(0x00000000), SHC(0x6fb07b54), SHC(0x6fb07b70), SHC(0x6fb07b80),
+ SHC(0x6fb07b94), SHC(0x6fb07bcd), SHC(0x6fb07be6), SHC(0x6fb07c0e), SHC(0x6fb07c43), SHC(0x6fb07c4d),
+ SHC(0x6fb07c8f), SHC(0x6fb07d49), SHC(0x6fb07d71), SHC(0x6fb07d9e), SHC(0x6fb07daf), SHC(0x6fb07dbd),
+ SHC(0x6fb07dcc), SHC(0x6fb07ddf), SHC(0x6fb07de7), SHC(0x6fb07df8), SHC(0x6fb07e05), SHC(0x6fb07e45),
+ SHC(0x00000000), SHC(0x6fb07b18), SHC(0x6fb07e60), SHC(0x6fb07e70), SHC(0x6fb07e8f), SHC(0x6fb07ec4),
+ SHC(0x6fb07ee1), SHC(0x6fb07f17), SHC(0x6fb07f3e), SHC(0x6fb07f67), SHC(0x6fb07fa2), SHC(0x6fb07fdf),
+ SHC(0x6fb07fed), SHC(0x00000000), SHC(0x63657865), SHC(0x705f656c), SHC(0x65672f2e), SHC(0x6f526574),
+ SHC(0x00726f74), SHC(0x65672f2e), SHC(0x6f526574), SHC(0x00726f74), SHC(0x4f52505f), SHC(0x7070413d),
+ SHC(0x696d7265), SHC(0x4c454853), SHC(0x622f6e69), SHC(0x4d524554), SHC(0x322d6d72), SHC(0x00726f6c),
+ SHC(0x2f3d5249), SHC(0x646c6f66), SHC(0x6e2f3238), SHC(0x36737636), SHC(0x78663431), SHC(0x3031785f),
+ SHC(0x2f542f33), SHC(0x52505f4d), SHC(0x45565f4d), SHC(0x34343d4e), SHC(0x44575044), SHC(0x2f737265),
+ SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x535f4d52), SHC(0x495f4e4f), SHC(0x34323939),
+ SHC(0x2d364133), SHC(0x4345382d), SHC(0x43344233), SHC(0x55003845), SHC(0x6d676c73), SHC(0x5455415f),
+ SHC(0x2f3d4b43), SHC(0x2f657461), SHC(0x2e6d6f63), SHC(0x616c2e65), SHC(0x64722e64), SHC(0x4b776b7a),
+ SHC(0x656e6574), SHC(0x3d485441), SHC(0x6d6f682f), SHC(0x69622f77), SHC(0x6c2f7273), SHC(0x6e69622f),
+ SHC(0x69622f72), SHC(0x2f3a6e69), SHC(0x6e696273), SHC(0x2f3a6e69), SHC(0x656d6f68), SHC(0x6e69622f),
+ SHC(0x31582f74), SHC(0x4c2f3a6e), SHC(0x412f7972), SHC(0x7273752f), SHC(0x70412f3a), SHC(0x6f697461),
+ SHC(0x61757369), SHC(0x6f696475), SHC(0x70612e65), SHC(0x6e65746e), SHC(0x756f7365), SHC(0x7070612f),
+ SHC(0x435f5f00), SHC(0x49656c64), SHC(0x65696669), SHC(0x70612e6d), SHC(0x6d726554), SHC(0x44575000),
+ SHC(0x2f737265), SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x74706972), SHC(0x643d474e),
+ SHC(0x4654552e), SHC(0x465f4350), SHC(0x3078303d), SHC(0x40755c3d), SHC(0x00202477), SHC(0x56524553),
+ SHC(0x454d414e), SHC(0x4c564c48), SHC(0x3d454d4f), SHC(0x732f7372), SHC(0x4e474f4c), SHC(0x6d676c73),
+ SHC(0x59414c50), SHC(0x74617669), SHC(0x6f632f70), SHC(0x2e656c70), SHC(0x2e646863), SHC(0x53386438)
+ };
+#endif
+const Word32 RotVector_960[2 * (480 - 60)] = {
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8),
+ SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x759af34c), SHC(0xcd790887), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x743e0918), SHC(0xca695b94), SHC(0x7387ea23), SHC(0xc8e5032b), SHC(0x72ccb9db), SHC(0xc763158e),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71474660), SHC(0xc466be4f), SHC(0x707d1443), SHC(0xc2ec7635),
+ SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6e010780), SHC(0xbe8df2ba),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6c40cf2c), SHC(0xbbb28501), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x697cf78a), SHC(0xb780001c), SHC(0x6887b5e2), SHC(0xb6201b3e),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x658c9a2d), SHC(0xb2141b02),
+ SHC(0x648543e4), SHC(0xb0c1878b), SHC(0x637984d4), SHC(0xaf726def), SHC(0x626968be), SHC(0xae26dcdf),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5cd91140), SHC(0xa7e3ff4d), SHC(0x5bafc837), SHC(0xa6aecd5e),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x581c00b3), SHC(0xa326eec0), SHC(0x55a6125c), SHC(0xa0e0a15f),
+ SHC(0x53211d18), SHC(0x9eab046f), SHC(0x508d9211), SHC(0x9c867b2c), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x487fffe4), SHC(0x96830876), SHC(0x45b6bb5e), SHC(0x94a6715d),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x40000000), SHC(0x9126145f), SHC(0x3d1389cb), SHC(0x8f82ebbd),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x371afcd5), SHC(0x8c7815dd), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2ddf0040), SHC(0x88806fc4), SHC(0x2aba2ee4), SHC(0x8757860c),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x1de189a6), SHC(0x838961e8), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x17537e63), SHC(0x8224b404),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0x0a0af299), SHC(0x80650347), SHC(0x06b2f1d2), SHC(0x802ce84c), SHC(0x0359c428), SHC(0x800b3a91),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2c4d9050), SHC(0x87e958a7), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0f0b7727), SHC(0x80e321ff), SHC(0x0a0af299), SHC(0x80650347),
+ SHC(0x05067734), SHC(0x80194350), SHC(0x00000000), SHC(0x80000000), SHC(0xfaf988cc), SHC(0x80194350),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xf0f488d9), SHC(0x80e321ff), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xe21e765a), SHC(0x838961e8), SHC(0xdd417079), SHC(0x84ce444e),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xcf043ab3), SHC(0x89be50c3),
+ SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc174dbf2), SHC(0x90520d04),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xacdee2e8), SHC(0x9eab046f), SHC(0xa91d0ea3), SHC(0xa201b853),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf94d0e2e), SHC(0x802ce84c), SHC(0xf29ecfb2), SHC(0x80b381ac),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe5632654), SHC(0x82cc0f36), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd220ffc0), SHC(0x88806fc4), SHC(0xcbf00dbe), SHC(0x8b10f144),
+ SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc0000000), SHC(0x9126145f), SHC(0xba4944a2), SHC(0x94a6715d),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaf726def), SHC(0x9c867b2c), SHC(0xaa59eda4), SHC(0xa0e0a15f),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0xa0e0a15f), SHC(0xaa59eda4), SHC(0x9c867b2c), SHC(0xaf726def),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x9126145f), SHC(0xc0000000),
+ SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x88806fc4), SHC(0xd220ffc0),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x82cc0f36), SHC(0xe5632654),
+ SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x802ce84c), SHC(0xf94d0e2e),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0xc0000000), SHC(0x9126145f),
+ SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xab9a8e6c), SHC(0x9fc3b694),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9fc3b694), SHC(0xab9a8e6c), SHC(0x9a7365d3), SHC(0xb2141b02),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8d334625), SHC(0xc763158e),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x86cafe57), SHC(0xd6db1254), SHC(0x845c8ae3), SHC(0xdedf047d),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x804628a7), SHC(0xf7a0dec9),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x804628a7), SHC(0x085f2137), SHC(0x811855b4), SHC(0x10b5150f),
+ SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x86cafe57), SHC(0x2924edac),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8d334625), SHC(0x389cea72), SHC(0x9126145f), SHC(0x40000000),
+ SHC(0x9592675c), SHC(0x471cece7), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0x9fc3b694), SHC(0x54657194),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9eab046f), SHC(0xacdee2e8), SHC(0x98722192), SHC(0xb4c373ee),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x838961e8), SHC(0xe21e765a), SHC(0x81936daf), SHC(0xebf9f498),
+ SHC(0x80650347), SHC(0xf5f50d67), SHC(0x80000000), SHC(0x00000000), SHC(0x80650347), SHC(0x0a0af299),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x838961e8), SHC(0x1de189a6), SHC(0x8643c7b3), SHC(0x278dde6e),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8df37f8b), SHC(0x3a1c5c57), SHC(0x92dcafe5), SHC(0x42e13ba4),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa57d8666), SHC(0x5a82799a),
+ SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xbd1ec45c), SHC(0x6d23501b),
+ SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xd8722192), SHC(0x79bc384d),
+ SHC(0xe21e765a), SHC(0x7c769e18), SHC(0xebf9f498), SHC(0x7e6c9251), SHC(0xf5f50d67), SHC(0x7f9afcb9),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x85c1e80e), SHC(0xda0aecf9), SHC(0x82cc0f36), SHC(0xe5632654),
+ SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0xfca63bd8), SHC(0x804628a7), SHC(0x085f2137),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x83f03dd6), SHC(0x1f81f37c), SHC(0x8757860c), SHC(0x2aba2ee4),
+ SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9126145f), SHC(0x40000000), SHC(0x97784a1e), SHC(0x49dfe4c2),
+ SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa6aecd5e), SHC(0x5bafc837), SHC(0xaf726def), SHC(0x637984d4),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xc2ec7635), SHC(0x707d1443), SHC(0xcd790887), SHC(0x759af34c),
+ SHC(0xd8722192), SHC(0x79bc384d), SHC(0xe3c02fbb), SHC(0x7cd80464), SHC(0xef4aeaf1), SHC(0x7ee7aa4c),
+ SHC(0xfaf988cc), SHC(0x7fe6bcb0), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x125df75b), SHC(0x7eace58a),
+ SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x2924edac), SHC(0x793501a9), SHC(0x340ff242), SHC(0x74ef0ebc),
+ SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x487fffe4), SHC(0x697cf78a), SHC(0x51d92321), SHC(0x626968be)};
+# endif
+
+#ifdef ENABLE_FFT_30X16
+/* Twiddle coefficients for 30x16 FFTs, generated by fft_tables.py */
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_30_16[2 * (480 - 30)] = {
+
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8),
+ SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d),
+ SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8),
+ SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67),
+ SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b),
+ SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd),
+ SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d),
+ SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a),
+ SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4),
+ SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e),
+ SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c),
+ SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e),
+ SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84),
+ SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83),
+ SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2),
+ SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6),
+ SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000),
+ SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443),
+ SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4),
+ SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c),
+ SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40),
+ SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d),
+ SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)};
+# endif
+#endif
+
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_360[2 * (360 - 30)] = {
+# else
+const Word16 RotVector_360[2 * (360 - 30)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce),
+ SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4),
+ SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d),
+ SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849),
+ SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2),
+ SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce),
+ SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582),
+ SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7),
+ SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce),
+ SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d),
+ SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e),
+ SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9),
+ SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b),
+ SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b),
+ SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7),
+ SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860),
+ SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17),
+ SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7),
+ SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57),
+ SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e),
+ SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7),
+ SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9),
+ SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b),
+ SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32),
+ SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422),
+ SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c),
+ SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d),
+ SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786),
+ SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b),
+ SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26),
+ SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49),
+ SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba),
+ SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d),
+ SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05)};
+
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_320[2 * (320 - 20)] = {
+# else
+const Word16 RotVector_320[2 * (320 - 20)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b),
+ SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x720c8075), SHC(0xc5e3a3a9),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x6154fb91), SHC(0xacdee2e8),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x14060b68), SHC(0x81936daf),
+ SHC(0x0a0af299), SHC(0x80650347), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9),
+ SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3),
+ SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9),
+ SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), SHC(0xe70747c4), SHC(0x8275a0c0),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8275a0c0), SHC(0xe70747c4),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x89be50c3), SHC(0x30fbc54d),
+ SHC(0x9592675c), SHC(0x471cece7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x14060b68), SHC(0x81936daf), SHC(0xf5f50d67), SHC(0x80650347),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x80650347), SHC(0xf5f50d67),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x98722192), SHC(0x4b3c8c12),
+ SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xe21e765a), SHC(0x7c769e18),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x6d23501b), SHC(0xbd1ec45c),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0xf5f50d67), SHC(0x80650347), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xb4c373ee), SHC(0x98722192),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x80e321ff), SHC(0xf0f488d9),
+ SHC(0x81936daf), SHC(0x14060b68), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9eab046f), SHC(0x53211d18),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xfaf988cc), SHC(0x7fe6bcb0),
+ SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7ff9af04), SHC(0xfd7ca4a6), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fc72ae2), SHC(0xf876ebe8),
+ SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f1cde01), SHC(0xf0f488d9),
+ SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e01b096), SHC(0xe97f81eb),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7a7d055b), SHC(0xdad7f3a2),
+ SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78ef678f), SHC(0xd61036db), SHC(0x7816a759), SHC(0xd3b26fb0),
+ SHC(0x77320d0d), SHC(0xd15907d9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fc72ae2), SHC(0xf876ebe8),
+ SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e01b096), SHC(0xe97f81eb), SHC(0x7c769e18), SHC(0xe21e765a),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7545a5a0), SHC(0xccb44322),
+ SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5c44ee40), SHC(0xa748e9ce),
+ SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4b3c8c12), SHC(0x98722192),
+ SHC(0x45027c0c), SHC(0x943239c7), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x37dc420c), SHC(0x8cd50c59),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7545a5a0), SHC(0xccb44322),
+ SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x56e2f15d), SHC(0xa201b853),
+ SHC(0x4930590f), SHC(0x96fd15e3), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x29efc925), SHC(0x87109871),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x07891418), SHC(0x8038d51e), SHC(0xf5f50d67), SHC(0x80650347),
+ SHC(0xe4918486), SHC(0x82f955ea), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc3a94590), SHC(0x8f1d343a),
+ SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa748e9ce), SHC(0xa3bb11c0), SHC(0x9b7abc1c), SHC(0xb0c1878b),
+ SHC(0x9191eb6e), SHC(0xbf469e83), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e01b096), SHC(0xe97f81eb),
+ SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6154fb91), SHC(0xacdee2e8),
+ SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x29efc925), SHC(0x87109871),
+ SHC(0x14060b68), SHC(0x81936daf), SHC(0xfd7ca4a6), SHC(0x800650fc), SHC(0xe70747c4), SHC(0x8275a0c0),
+ SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xaaf9c6af), SHC(0xa051a5ab),
+ SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8643c7b3), SHC(0xd8722192),
+ SHC(0x8135061b), SHC(0xee76612d), SHC(0x80194350), SHC(0x05067734), SHC(0x82f955ea), SHC(0x1b6e7b7a),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x743e0918), SHC(0xca695b94),
+ SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x3c56ba70), SHC(0x8f1d343a),
+ SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x07891418), SHC(0x8038d51e), SHC(0xebf9f498), SHC(0x81936daf),
+ SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa3bb11c0), SHC(0xa748e9ce),
+ SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x87109871), SHC(0xd61036db), SHC(0x80e321ff), SHC(0xf0f488d9),
+ SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x9191eb6e), SHC(0x40b9617d),
+ SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xb6cfa6f1), SHC(0x6902ea1d), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x5c44ee40), SHC(0xa748e9ce),
+ SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x05067734), SHC(0x80194350),
+ SHC(0xe4918486), SHC(0x82f955ea), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xaaf9c6af), SHC(0xa051a5ab),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x87109871), SHC(0xd61036db), SHC(0x80650347), SHC(0xf5f50d67),
+ SHC(0x81fe4f6a), SHC(0x16807e15), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9d0dfe54), SHC(0x5133cc94),
+ SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xd15907d9), SHC(0x77320d0d), SHC(0xf0f488d9), SHC(0x7f1cde01),
+ SHC(0x11899ed3), SHC(0x7ecaf9e5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7a7d055b), SHC(0xdad7f3a2),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xc3a94590), SHC(0x8f1d343a),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8275a0c0), SHC(0xe70747c4),
+ SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9d0dfe54), SHC(0x5133cc94),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0x00000000), SHC(0x7fffffff),
+ SHC(0x25280c5e), SHC(0x7a7d055b), SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x62f201ac), SHC(0x5133cc94)};
+
+
+/* Twiddle coefficients for 32x8 FFTs, generated by fft_tables.py */
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_32_8[2 * (256 - 32)] = {
+# else
+const Word16 RotVector_32_8[2 * (256 - 32)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff62182), SHC(0xfcdbd541), SHC(0x7fd8878e), SHC(0xf9b82684),
+ SHC(0x7fa736b4), SHC(0xf6956fb7), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f0991c4), SHC(0xf054d8d5),
+ SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7b5d039e), SHC(0xdddc5b3b),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x798a23b1), SHC(0xd7d946d8), SHC(0x78848414), SHC(0xd4e0cb15),
+ SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x7504d345), SHC(0xcc210d79),
+ SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72552c85), SHC(0xc67322ce), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6c242960), SHC(0xbb8532b0),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x66cf8120), SHC(0xb3c0200c),
+ SHC(0x64e88926), SHC(0xb140175b), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x60ec3830), SHC(0xac64d510),
+ SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5cb420e0), SHC(0xa7bd22ac), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2),
+ SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec),
+ SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x66cf8120), SHC(0xb3c0200c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54),
+ SHC(0x4c3fdff4), SHC(0x99307ee0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec),
+ SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971),
+ SHC(0x0647d97c), SHC(0x80277872), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fa736b4), SHC(0xf6956fb7),
+ SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7a7d055b), SHC(0xdad7f3a2),
+ SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6f5f02b2), SHC(0xc0e8b648),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x64e88926), SHC(0xb140175b), SHC(0x5ed77c8a), SHC(0xaa0a5b2e),
+ SHC(0x5842dd54), SHC(0xa34bdf20), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x49b41533), SHC(0x9759617f),
+ SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x398cdd32), SHC(0x8daad37b), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x2826b928), SHC(0x8675dc4f), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x15e21445), SHC(0x81e26c16),
+ SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x03242abf), SHC(0x8009de7e), SHC(0xf9b82684), SHC(0x80277872),
+ SHC(0xf054d8d5), SHC(0x80f66e3c), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdddc5b3b), SHC(0x84a2fc62),
+ SHC(0xd4e0cb15), SHC(0x877b7bec), SHC(0xcc210d79), SHC(0x8afb2cbb), SHC(0xc3a94590), SHC(0x8f1d343a),
+ SHC(0xbb8532b0), SHC(0x93dbd6a0), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xac64d510), SHC(0x9f13c7d0),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0xcf043ab3), SHC(0x89be50c3),
+ SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaecc336c), SHC(0x9d0dfe54),
+ SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9592675c), SHC(0xb8e31319),
+ SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8582faa5), SHC(0xdad7f3a2),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7f0991c4), SHC(0xf054d8d5), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x776c4edb), SHC(0xd1eef59e),
+ SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x5ed77c8a), SHC(0xaa0a5b2e),
+ SHC(0x539b2af0), SHC(0x9f13c7d0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x398cdd32), SHC(0x8daad37b),
+ SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x1c0b826a), SHC(0x831c314e), SHC(0x0c8bd35e), SHC(0x809dc971),
+ SHC(0xfcdbd541), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdddc5b3b), SHC(0x84a2fc62),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0e8b648), SHC(0x90a0fd4e), SHC(0xb3c0200c), SHC(0x99307ee0),
+ SHC(0xa7bd22ac), SHC(0xa34bdf20), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x93dbd6a0), SHC(0xbb8532b0),
+ SHC(0x8c4a142f), SHC(0xc945dfec), SHC(0x8675dc4f), SHC(0xd7d946d8), SHC(0x8275a0c0), SHC(0xe70747c4),
+ SHC(0x8058c94c), SHC(0xf6956fb7), SHC(0x80277872), SHC(0x0647d97c), SHC(0x81e26c16), SHC(0x15e21445),
+ SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8afb2cbb), SHC(0x33def287), SHC(0x9235f2ec), SHC(0x41ce1e65),
+ SHC(0x9b1776da), SHC(0x4ebfe8a5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971),
+ SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec),
+ SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e),
+ SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65),
+ SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4),
+ SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x78848414), SHC(0xd4e0cb15),
+ SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x539b2af0), SHC(0x9f13c7d0),
+ SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x2e110a62), SHC(0x8893b125), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0x03242abf), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xd7d946d8), SHC(0x8675dc4f),
+ SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb140175b), SHC(0x9b1776da), SHC(0xa1288376), SHC(0xaa0a5b2e),
+ SHC(0x93dbd6a0), SHC(0xbb8532b0), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x831c314e), SHC(0xe3f47d96),
+ SHC(0x80277872), SHC(0xf9b82684), SHC(0x80f66e3c), SHC(0x0fab272b), SHC(0x8582faa5), SHC(0x25280c5e),
+ SHC(0x8daad37b), SHC(0x398cdd32), SHC(0x99307ee0), SHC(0x4c3fdff4), SHC(0xa7bd22ac), SHC(0x5cb420e0),
+ SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcc210d79), SHC(0x7504d345), SHC(0xe0e60685), SHC(0x7c29fbee),
+ SHC(0xf6956fb7), SHC(0x7fa736b4), SHC(0x0c8bd35e), SHC(0x7f62368f), SHC(0x2223a4c5), SHC(0x7b5d039e),
+ SHC(0x36ba2014), SHC(0x73b5ebd1), SHC(0x49b41533), SHC(0x68a69e81)};
+
+
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_15_6[2 * (90 - 15)] = {
+# else
+const Word16 RotVector_15_6[2 * (90 - 15)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369),
+ SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46),
+ SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x74ef0ebc), SHC(0xcbf00dbe),
+ SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x40000000), SHC(0x9126145f),
+ SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x80b381ac),
+ SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xaa59eda4), SHC(0xa0e0a15f),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x82cc0f36), SHC(0xe5632654),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x6c8cd70b), SHC(0xbc2b9b05),
+ SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x163a1a7e), SHC(0x81f1d1ce),
+ SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xb1320139), SHC(0x9b2276b0),
+ SHC(0x98722192), SHC(0xb4c373ee), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x804fd23a), SHC(0xf7123849),
+ SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x8efb92c2), SHC(0x3c17a4e8), SHC(0xa3ecac65), SHC(0x58ea90c4),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7847d909), SHC(0xd438af17), SHC(0x620dbe8b), SHC(0xadb922b7),
+ SHC(0x40000000), SHC(0x9126145f), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0xe9c5e582), SHC(0x81f1d1ce),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x87b826f7), SHC(0xd438af17),
+ SHC(0x80000000), SHC(0x00000000), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x9df24175), SHC(0x5246dd49),
+ SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xe9c5e582), SHC(0x7e0e2e32), SHC(0x163a1a7e), SHC(0x7e0e2e32)};
+
+#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB)
+/* Twiddle coefficients for 32x12 FFTs, generated by fft_tables.py */
+# ifdef ENABLE_HR_MODE
+const Word32 RotVector_32_12[2 * (384 - 32)] = {
+# else
+const Word16 RotVector_32_12[2 * (384 - 32)] = {
+# endif
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb9d15), SHC(0xfde7dbd9), SHC(0x7fee74a2), SHC(0xfbcfdc71),
+ SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f92661d), SHC(0xf58a29f2),
+ SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7deeaa7a), SHC(0xe915f9ba),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d1d7958), SHC(0xe4fa4bf1), SHC(0x7ca80038), SHC(0xe2ef2a3e),
+ SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b1474fd), SHC(0xdcda47b9),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x79dd3098), SHC(0xd8d82b7a), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x770acdec), SHC(0xd0f53ce0),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x74972f92), SHC(0xcb2c6a82),
+ SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x71dba9ab), SHC(0xc5842c7e),
+ SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6fe2313c), SHC(0xc1d2814f), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7fee74a2), SHC(0xfbcfdc71), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f62368f), SHC(0xf3742ca2),
+ SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7ca80038), SHC(0xe2ef2a3e), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7a7d055b), SHC(0xdad7f3a2),
+ SHC(0x793501a9), SHC(0xd6db1254), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x74972f92), SHC(0xcb2c6a82), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6cb2a837), SHC(0xbc6845ce), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x680b5c33), SHC(0xb5715eef), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x62f201ac), SHC(0xaecc336c),
+ SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5d6c2f99), SHC(0xa8800c26), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x577ff3da), SHC(0xa293d067), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x5133cc94), SHC(0x9d0dfe54),
+ SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x4a8ea111), SHC(0x97f4a3cd), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x4397ba32), SHC(0x934d57c9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd8878e), SHC(0xf9b82684),
+ SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7d8a5f40), SHC(0xe70747c4),
+ SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x78848414), SHC(0xd4e0cb15),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x66cf8120), SHC(0xb3c0200c),
+ SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4c3fdff4), SHC(0x99307ee0),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x3c56ba70), SHC(0x8f1d343a),
+ SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2b1f34eb), SHC(0x877b7bec),
+ SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x18f8b83c), SHC(0x8275a0c0),
+ SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x0647d97c), SHC(0x80277872),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000),
+ SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7),
+ SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4),
+ SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7f92661d), SHC(0xf58a29f2), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7c29fbee), SHC(0xe0e60685),
+ SHC(0x793501a9), SHC(0xd6db1254), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x70e2cbc6), SHC(0xc3a94590),
+ SHC(0x6b93d02e), SHC(0xbaa34bf4), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5ed77c8a), SHC(0xaa0a5b2e),
+ SHC(0x577ff3da), SHC(0xa293d067), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x3e2d7eb1), SHC(0x901dcec4), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2b1f34eb), SHC(0x877b7bec),
+ SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x16ea0646), SHC(0x82115586), SHC(0x0c8bd35e), SHC(0x809dc971),
+ SHC(0x02182427), SHC(0x800462eb), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xed37ef91), SHC(0x8162aa04),
+ SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xd8d82b7a), SHC(0x8622cf68), SHC(0xcf043ab3), SHC(0x89be50c3),
+ SHC(0xc5842c7e), SHC(0x8e245655), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xb3c0200c), SHC(0x99307ee0),
+ SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa405847e), SHC(0xa6fbbc59), SHC(0x9d0dfe54), SHC(0xaecc336c),
+ SHC(0x96bfea3d), SHC(0xb727b9f7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2),
+ SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c),
+ SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c),
+ SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xf3742ca2), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c),
+ SHC(0xaecc336c), SHC(0x9d0dfe54), SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c),
+ SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x8582faa5), SHC(0xdad7f3a2), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ca80038), SHC(0xe2ef2a3e),
+ SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6b93d02e), SHC(0xbaa34bf4),
+ SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x590443a7), SHC(0xa405847e), SHC(0x4debe4fe), SHC(0x9a7365d3),
+ SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2727d486), SHC(0x8622cf68),
+ SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0a75d60e), SHC(0x806d99e3), SHC(0xfbcfdc71), SHC(0x80118b5e),
+ SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd0f53ce0), SHC(0x88f53214),
+ SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb727b9f7), SHC(0x96bfea3d), SHC(0xab9a8e6c), SHC(0x9fc3b694),
+ SHC(0xa1288376), SHC(0xaa0a5b2e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x901dcec4), SHC(0xc1d2814f),
+ SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x84eb8b03), SHC(0xdcda47b9), SHC(0x81b5abda), SHC(0xeb263dbb),
+ SHC(0x80277872), SHC(0xf9b82684), SHC(0x804628a7), SHC(0x085f2137), SHC(0x82115586), SHC(0x16ea0646),
+ SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8a8f8a54), SHC(0x32e96c09), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7641af3d), SHC(0xcf043ab3),
+ SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5a82799a), SHC(0xa57d8666),
+ SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), SHC(0x30fbc54d), SHC(0x89be50c3),
+ SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x00000000), SHC(0x80000000),
+ SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xcf043ab3), SHC(0x89be50c3),
+ SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), SHC(0x89be50c3), SHC(0xcf043ab3),
+ SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x80000000), SHC(0x00000000),
+ SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x89be50c3), SHC(0x30fbc54d),
+ SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0xa57d8666), SHC(0x5a82799a),
+ SHC(0xb2141b02), SHC(0x658c9a2d), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91),
+ SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319),
+ SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec),
+ SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971),
+ SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec),
+ SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666),
+ SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e),
+ SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65),
+ SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4),
+ SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc),
+ SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x793501a9), SHC(0xd6db1254),
+ SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x577ff3da), SHC(0xa293d067),
+ SHC(0x471cece7), SHC(0x9592675c), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2120fb83), SHC(0x845c8ae3),
+ SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xe2ef2a3e), SHC(0x8357ffc8),
+ SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xab9a8e6c), SHC(0x9fc3b694),
+ SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9126145f), SHC(0xc0000000), SHC(0x88343c0e), SHC(0xd2e9786e),
+ SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80118b5e), SHC(0xfbcfdc71), SHC(0x811855b4), SHC(0x10b5150f),
+ SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x97f4a3cd), SHC(0x4a8ea111),
+ SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb5715eef), SHC(0x680b5c33), SHC(0xc763158e), SHC(0x72ccb9db),
+ SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x0430238f), SHC(0x7fee74a2),
+ SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x2d168792), SHC(0x77cbc3f2), SHC(0x7fffffff), SHC(0x00000000),
+ SHC(0x7deeaa7a), SHC(0xe915f9ba), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x6dca0d14), SHC(0xbe31e19b),
+ SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x3c56ba70), SHC(0x8f1d343a),
+ SHC(0x2727d486), SHC(0x8622cf68), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xf9b82684), SHC(0x80277872),
+ SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xcd1693f7), SHC(0x8a8f8a54), SHC(0xb8e31319), SHC(0x9592675c),
+ SHC(0xa6fbbc59), SHC(0xa405847e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x8c4a142f), SHC(0xc945dfec),
+ SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x806d99e3), SHC(0xf58a29f2), SHC(0x809dc971), SHC(0x0c8bd35e),
+ SHC(0x84eb8b03), SHC(0x2325b847), SHC(0x8d334625), SHC(0x389cea72), SHC(0x99307ee0), SHC(0x4c3fdff4),
+ SHC(0xa8800c26), SHC(0x5d6c2f99), SHC(0xbaa34bf4), SHC(0x6b93d02e), SHC(0xcf043ab3), SHC(0x7641af3d),
+ SHC(0xe4fa4bf1), SHC(0x7d1d7958), SHC(0xfbcfdc71), SHC(0x7fee74a2), SHC(0x12c8106f), SHC(0x7e9d55fc),
+ SHC(0x2924edac), SHC(0x793501a9), SHC(0x3e2d7eb1), SHC(0x6fe2313c), SHC(0x5133cc94), SHC(0x62f201ac),
+ SHC(0x619a7dce), SHC(0x52cf758f)};
+
+
+# endif /* !defined(__XTENSA__) */
+
+
+/* Inverse square root table for operands running from 0.5 to ~1.0
+
+ (Word32) (0.5 + 1.0/sqrt((op)/CDKpow(2.0,31)))
+
+ Note: First value is not rounded for accuracy reasons
+
+ Implicit exponent is 1
+
+ Example: 0x5A82799A = Isqrt(0x40000000), exponent=1
+*/
+const Word32 isqrt_table[128 + 2] = {
+ 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D,
+ 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0,
+ 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F,
+ 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7,
+ 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9,
+ 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294,
+ 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3,
+ 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D,
+ 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81,
+ 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88,
+ 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B,
+ 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398,
+ 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8,
+ 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22,
+ 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC,
+};
+
+const Word32 Log2_16_table1[16] = {
+ 0, 2934766, 5701737, 8319067, 10802114, 13163988, 15415967, 17567824,
+ 19628084, 21604229, 23502857, 25329821, 27090336, 28789065, 30430199, 32017515,
+};
+
+const Word16 Log2_16_table2[16] = {
+ 1433, 1351, 1278, 1212, 1153, 1099, 1051, 1006, 965, 927, 892, 860, 829, 801, 775, 750,
+};
+
+const Word32 InvLog2_16_table1[64] = {
+ 1073741824, 1085434106, 1097253708, 1109202018, 1121280436, 1133490379, 1145833280, 1158310587,
+ 1170923762, 1183674286, 1196563654, 1209593378, 1222764986, 1236080024, 1249540052, 1263146652,
+ 1276901417, 1290805962, 1304861917, 1319070932, 1333434672, 1347954824, 1362633090, 1377471191,
+ 1392470869, 1407633882, 1422962010, 1438457051, 1454120821, 1469955159, 1485961921, 1502142985,
+ 1518500250, 1535035634, 1551751076, 1568648537, 1585730000, 1602997467, 1620452965, 1638098541,
+ 1655936265, 1673968228, 1692196547, 1710623359, 1729250827, 1748081133, 1767116489, 1786359126,
+ 1805811301, 1825475297, 1845353420, 1865448001, 1885761398, 1906295993, 1927054196, 1948038440,
+ 1969251188, 1990694927, 2012372174, 2034285470, 2056437387, 2078830522, 2101467502, 2124350982,
+};
+
+const Word16 InvLog2_16_table2[64] = {
+ 11418, 11543, 11668, 11795, 11924, 12054, 12185, 12318, 12452, 12587, 12724, 12863, 13003, 13145, 13288, 13432,
+ 13579, 13727, 13876, 14027, 14180, 14334, 14490, 14648, 14808, 14969, 15132, 15297, 15463, 15632, 15802, 15974,
+ 16148, 16324, 16501, 16681, 16863, 17046, 17232, 17420, 17609, 17801, 17995, 18191, 18389, 18589, 18792, 18996,
+ 19203, 19412, 19624, 19837, 20053, 20272, 20492, 20716, 20941, 21169, 21400, 21633, 21868, 22106, 22347, 22590,
+};
+
+const UWord8 gf16_mult_table[256] = {
+ /* gf16_mult_table[a | (b << 4)] contains the product of a and b in GF(16) */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13, 0, 3, 6, 5, 12, 15, 10, 9, 11, 8,
+ 13, 14, 7, 4, 1, 2, 0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9, 0, 5, 10, 15, 7, 2, 13,
+ 8, 14, 11, 4, 1, 9, 12, 3, 6, 0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4, 0, 7, 14, 9,
+ 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11, 0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1, 0,
+ 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14, 0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11,
+ 6, 12, 0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3, 0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1,
+ 13, 15, 3, 4, 8, 0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7, 0, 14, 15, 1, 13, 3, 2, 12,
+ 9, 7, 6, 8, 4, 10, 11, 5, 0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10,
+};
+
+const UWord8 rs16_elp_deg2_table[256] = {
+ /* If the polynomial x^2 + ax + b has distinct non-zero roots z1 and z2 in GF(16), *
+ * then table entry a + 16*b contains log_g(z1) | log_g(z2) << 4, and otherwise it *
+ * contains 0. */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0,
+ 105, 195, 0, 210, 0, 225, 0, 180, 120, 0, 0, 121, 0, 16, 0, 211, 0, 0, 181, 0, 0, 106,
+ 196, 226, 0, 0, 0, 214, 64, 0, 199, 0, 0, 0, 0, 0, 49, 184, 0, 154, 0, 229, 0, 227,
+ 182, 0, 0, 32, 0, 0, 0, 197, 0, 0, 122, 0, 212, 152, 0, 203, 0, 158, 128, 0, 0, 0,
+ 98, 113, 218, 0, 0, 0, 53, 0, 0, 65, 0, 0, 185, 110, 215, 80, 0, 0, 200, 0, 50, 0,
+ 0, 0, 0, 130, 205, 115, 0, 0, 160, 190, 145, 0, 0, 0, 0, 0, 0, 100, 0, 0, 168, 198,
+ 0, 183, 33, 0, 0, 48, 228, 213, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 179, 0, 224, 104,
+ 0, 194, 149, 0, 0, 209, 0, 0, 0, 189, 99, 84, 0, 129, 0, 0, 0, 144, 0, 0, 234, 114,
+ 0, 0, 82, 0, 0, 0, 0, 217, 202, 0, 112, 52, 232, 0, 97, 0, 0, 0, 126, 0, 81, 201,
+ 0, 36, 216, 186, 0, 0, 0, 96, 0, 0, 0, 0, 0, 88, 0, 0, 0, 103, 0, 148, 178, 0,
+ 208, 193, 0, 58, 0, 0, 0, 0, 0, 161, 206, 0, 116, 0, 101, 0, 0, 56, 146, 176, 0, 0,
+ 147, 162, 222, 0, 132, 0, 0, 0, 0, 0, 177, 117, 192, 0,
+};
+
+const UWord16 rs16_elp_deg3_table[256] = {
+ /* If the polynomial x^3 + ax + b has distinct roots z1, z2 and z3 in GF(16), *
+ * then table entry a + 16*b contains z1) | z2 << 4 | z3 << 8, and otherwise it *
+ * contains 0. */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1889, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2977, 0, 0, 0, 0, 0, 3990, 1859, 0,
+ 0, 0, 0, 0, 0, 0, 3521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1874, 0, 3718, 0, 0, 0,
+ 0, 0, 0, 2433, 0, 0, 1619, 0, 0, 0, 0, 3495, 0, 0, 0, 0, 0, 0, 4065, 0, 0, 0,
+ 0, 0, 0, 3255, 0, 0, 0, 1602, 0, 3735, 0, 0, 0, 0, 3238, 801, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3510, 0, 0, 0, 0, 1345, 3975, 0, 0, 0, 0, 0, 0, 0, 0, 3778, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2947, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3476, 0, 4005, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3748, 0, 0, 2962, 0, 0, 0, 0, 4035, 0, 0, 4020, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3221, 0, 0, 0, 0, 0, 0, 2690,
+ 0, 0, 0, 3795, 0, 0, 0, 4050, 0, 0, 0, 0, 0, 3204, 3765, 0, 0, 0, 0, 0, 2707, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+#ifdef ENABLE_HR_MODE
+const Word32 invSqrtTab[(128 + 2)] = {
+ 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D,
+ 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0,
+ 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F,
+ 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7,
+ 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9,
+ 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294,
+ 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3,
+ 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D,
+ 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81,
+ 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88,
+ 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B,
+ 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398,
+ 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8,
+ 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22,
+ 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC /* , 0x3FC05F61 */
+};
+#endif
diff --git a/lib_lc3plus/rom_basop_util.h b/lib_lc3plus/rom_basop_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e757c339355d3b4f939348c27e18a6df6dedd4b
--- /dev/null
+++ b/lib_lc3plus/rom_basop_util.h
@@ -0,0 +1,172 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef __BASOP_UTIL_ROM_H__
+#define __BASOP_UTIL_ROM_H__
+
+#include "basop_util_lc3plus.h"
+#include "functions.h"
+
+#define LD_INT_TAB_LEN 120
+#define INV_TABLE_SIZE 256
+#define SQRT_TABLE_SIZE 256
+
+#ifndef CHEAP_NORM_SIZE
+#define CHEAP_NORM_SIZE 161
+#endif
+
+#define MINSFTAB 7
+#define MAXSFTAB 25
+
+#ifdef ENABLE_HR_MODE
+#define SHC(x) ((Word32)x)
+#else
+#define SHC(x) WORD322WORD16((Word32)x)
+#endif
+
+/**
+ * \brief Lookup-Table for binary logarithm
+ */
+extern const Word16 ldCoeff_lc3plus[7];
+
+/**
+ \brief Lookup-Table for binary power algorithm
+*/
+extern const UWord32 exp2_tab_long_lc3plus[32];
+
+/**
+ \brief Lookup-Table for binary power algorithm
+*/
+extern const UWord32 exp2w_tab_long_lc3plus[32];
+
+/**
+ \brief Lookup-Table for binary power algorithm
+*/
+extern const UWord32 exp2x_tab_long_lc3plus[32];
+
+/**
+ * \brief 1/x, x=[0,1,2,3...] table
+ */
+#ifdef ENABLE_HR_MODE
+extern const Word16 InvIntTable[74];
+#else
+extern const Word16 InvIntTable[32];
+#endif
+
+/**
+ * \ brief Lookup for sine tables and windows.
+ */
+void BASOP_getTables(
+#ifdef ENABLE_HR_MODE
+ const PWord32 **ptwiddle,
+ const PWord32 **sin_twiddle,
+#else
+ const PWord16 **ptwiddle,
+ const PWord16 **sin_twiddle,
+#endif
+ Word16 *sin_step,
+ Word16 length);
+
+extern const Word32 RealFFT20_twid[6];
+extern const Word32 RealFFT32_twid[10];
+extern const Word32 RealFFT40_twid[12];
+extern const Word32 RealFFT60_twid[17];
+extern const Word32 RealFFT64_twid[18];
+extern const Word32 RealFFT80_twid[22];
+extern const Word32 RealFFT96_twid[26];
+extern const Word32 RealFFT128_twid[34];
+extern const Word32 RealFFT192_twid[50];
+extern const Word32 RealFFT256_twid[66];
+extern const Word32 RealFFT384_twid[98];
+extern const Word32 RealFFT512_twid[130];
+extern const Word32 RealFFT768_twid[194];
+
+#ifdef ENABLE_HR_MODE
+extern const PWord32 SineTable480[241];
+extern const PWord32 SineTable320[161];
+extern const PWord32 SineTable960[481];
+#else
+extern const PWord16 SineTable480[241];
+extern const PWord16 SineTable320[161];
+extern const PWord16 SineTable960[481];
+#endif
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_15_6[2 * (90 - 15)];
+#else
+extern const Word16 RotVector_15_6[2 * (90 - 15)];
+#endif
+
+extern const Word32 RotVector_32_32[2 * 20];
+extern const Word32 RotVector_40_32[2 * 28];
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_320[2 * (320 - 20)];
+#else
+extern const Word16 RotVector_320[2 * (320 - 20)];
+#endif
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_360[2 * (360 - 30)];
+#else
+extern const Word16 RotVector_360[2 * (360 - 30)];
+#endif
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_480[2 * (480 - 30)];
+#else
+extern const Word16 RotVector_480[2 * (480 - 30)];
+#endif
+
+#ifdef ENABLE_HR_MODE
+#ifdef CR8_G_ADD_75MS
+extern const Word32 RotVector_720[2 * (720 - 30)];
+#endif
+extern const Word32 RotVector_960[2 * (480 - 60)];
+#else
+extern const Word16 RotVector_960[2 * (480 - 60)];
+#endif
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_30_16[2 * (480 - 30)];
+#endif
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_32_8[2 * (256 - 32)];
+#else
+extern const Word16 RotVector_32_8[2 * (256 - 32)];
+#endif
+
+#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB)
+#ifdef ENABLE_HR_MODE
+extern const Word32 RotVector_32_12[2 * (384 - 32)];
+#else
+extern const Word16 RotVector_32_12[2 * (384 - 32)];
+#endif
+#else
+#define RotVector_32_12 NULL
+#endif
+
+extern const Word32 isqrt_table[128 + 2];
+
+extern const Word32 Log2_16_table1[16];
+extern const Word16 Log2_16_table2[16];
+
+extern const Word32 InvLog2_16_table1[64];
+extern const Word16 InvLog2_16_table2[64];
+
+extern const UWord8 gf16_mult_table[256];
+extern const UWord8 rs16_elp_deg2_table[256];
+extern const UWord16 rs16_elp_deg3_table[256];
+
+#ifdef ENABLE_HR_MODE
+extern const Word32 invSqrtTab[(128 + 2)];
+#endif
+
+#endif
diff --git a/lib_lc3plus/scale_signal24_fx.c b/lib_lc3plus/scale_signal24_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..548788d2a020f96bc64b48ff5ec6833edfa1e4f0
--- /dev/null
+++ b/lib_lc3plus/scale_signal24_fx.c
@@ -0,0 +1,121 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void scale_signal24_fx(Word32 x[], /* i: time input signal */
+#ifdef ENABLE_HR_MODE
+ Word32 x_scaled[],
+#else
+ Word16 x_scaled[],
+#endif
+ Word16 *x_exp,
+#ifdef ENABLE_HR_MODE
+ Word32 mdct_mem[],
+#else
+ Word16 mdct_mem[],
+#endif
+ Word16 mdct_mem_len,
+ Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[],
+ Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N,
+ Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale)
+{
+ Word16 i;
+ Word16 s;
+ Word16 scales[6];
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("scale_signal24_fx", sizeof(struct {
+ Word16 i;
+ Word16 s;
+ Word16 scales[6];
+ }));
+#endif
+
+ /* Scale input for 24 bit case */
+ /* assure 24 bit input */
+ FOR (i = 0; i < N; i++)
+ {
+ IF (x[i] >= 0)
+ {
+ x[i] = L_and(x[i], 0x007fffff);
+ }
+ ELSE
+ {
+ x[i] = (Word32)L_or( (UWord32)x[i], 0xff800000);
+ }
+ }
+
+ /* Find maximum exponent */
+ scales[0] = sub(15 + 8, getScaleFactor32_0(x, N));
+ scales[1] = sub(15 + 8, getScaleFactor32_0(mdct_mem32, mdct_mem_len));
+ scales[2] = sub(15 + 8, getScaleFactor32_0(resamp_mem32, resample_mem_in_len));
+ scales[3] = sub(sub(*resamp_scale, 2), getScaleFactor32_0(resample_mem_in50, 2));
+ scales[4] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(resample_mem_out, resample_mem_out_len));
+ scales[5] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(mem_s12k8, 3));
+ *x_exp = 7; move16();
+ FOR (i = 0; i < 6; i++)
+ {
+ *x_exp = s_max(*x_exp, scales[i]); move16();
+ }
+
+ /* Shift input buffers */
+ s = sub(15 + 8, *x_exp);
+ FOR (i = 0; i < N; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ x_scaled[i] = L_shl(x[i], s);
+#else
+ x_scaled[i] = round_fx_sat(L_shl(x[i], s));
+#endif
+ }
+
+ FOR (i = 0; i < mdct_mem_len; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ mdct_mem[i] = L_shl(mdct_mem32[i], s);
+#else
+ mdct_mem[i] = round_fx_sat(L_shl(mdct_mem32[i], s));
+#endif
+ }
+
+ FOR (i = 0; i < resample_mem_in_len; i++)
+ {
+ resample_mem_in[i] = round_fx_sat(L_shl(resamp_mem32[i], s));
+ }
+
+ /* Adjust resampler filter and output buffers */
+ s = sub(sub(*resamp_scale, 2), *x_exp);
+ *resamp_scale = add(*x_exp, 2);
+
+ IF (s)
+ {
+ FOR (i = 0; i < 2; i++)
+ {
+ resample_mem_in50[i] = L_shl(resample_mem_in50[i], s);
+ }
+ FOR (i = 0; i < resample_mem_out_len; i++)
+ {
+ resample_mem_out[i] = shl(resample_mem_out[i], s);
+ }
+
+ FOR (i = 0; i < 3; i++)
+ {
+ mem_s12k8[i] = shl(mem_s12k8[i], s);
+ }
+ }
+ /* Store part of current frame as mdct memory buffer and resampler input buffer for next frame */
+ basop_memcpy(mdct_mem32, &x[N - mdct_mem_len], mdct_mem_len * sizeof(Word32));
+ basop_memmove(resamp_mem32, &x[N - resample_mem_in_len], resample_mem_in_len * sizeof(Word32));
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d2849f565386fa7cb61b400f15c7bc1d0234c4c
--- /dev/null
+++ b/lib_lc3plus/setup_dec_lc3.c
@@ -0,0 +1,539 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "setup_dec_lc3.h"
+
+/* if decoder is null only size is reported */
+/*assume 10ms for memory allocation for now */
+int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels)
+{
+ int ch = 0;
+ size_t size = sizeof(LC3PLUS_Dec);
+ void * ltpf_mem_x = NULL, *ltpf_mem_y = NULL, *stDec_ola_mem_fx = NULL;
+ int max_len = DYN_MAX_LEN_EXT(samplerate); /*NB sing 80 as minimum value changes BE for NB */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL;
+ Word16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0;
+#endif
+
+ void *q_old_res_fx = NULL;
+ Word16 *sharedBuf = NULL;
+#if defined(ENABLE_PC)
+ void *q_old_d_fx = NULL;
+#endif
+ void *plcAd = NULL, *PhECU_f0est = NULL, *PhECU_plocs = NULL;
+
+ for (ch = 0; ch < channels; ch++)
+ {
+ DecSetup *setup = balloc(decoder, &size, sizeof(DecSetup));
+#ifdef ENABLE_HR_MODE
+ int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW_HR);
+#else
+ int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW );
+#endif
+ int x_old_len = DYN_MAX_LEN_PCM_PLC(samplerate); /* max(pitchmax + frame ms, M+1 + pitchmax + frame/2) */
+ int fs_idx = (samplerate / 10000); /* floor= integer truncation is needed here */
+
+ ltpf_mem_x = balloc(decoder, &size, sizeof(*setup->ltpf_mem_x) * (max_len + max_len / 40 - 2));
+ ltpf_mem_y =
+ balloc(decoder, &size,
+ sizeof(*setup->ltpf_mem_y) * (max_len + CEILING(MAX_PITCH_12K8 * max_len, 128) + (max_len / 80)));
+
+ stDec_ola_mem_fx = balloc(decoder, &size, sizeof(*setup->stDec_ola_mem_fx) * DYN_MAX_MDCT_LEN(samplerate));
+
+#if defined(ENABLE_PC)
+ q_old_d_fx = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len);
+#endif
+ sharedBuf = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len + sizeof(*setup->plcAd->x_old_tot_fx) * x_old_len);
+
+ /* To save static RAM, a large buffer sharedBuf is used to share
+ * space for q_old_d_fx, x_old_tot_fx and X_sav_fx (note:
+ * PHASE_ECU operates only at 10ms and standard precision)
+ *
+ * If partial Concealment is active, q_old_d_fx is saved in a separate buffer
+ *
+ * The following graph provides an overview about the memory
+ * sharing for 10ms and normal resolution:
+ */
+
+ /* Total buffer | <--- sharedBuf ---> | */
+ /* ConcealMethod 3or4 | <---q_old_d_fx---> | <-------------------- x_old_tot_fx ------------------> | */
+ /* ConcealMethod 3 | <---q_old_d_fx---> | |<------- M+1+pitch_max+ (frame_len/2)----------> | */ /* first BFI-frame only? */
+ /* Meth 2,prevBfi=0 | | <------- 16 ms xfp ------->| */
+ /* Meth 2 | ^ X_sav_fx ptr | <-------- maintained old_tot_fx ---------> | */ /* pitchmax samples maintained */
+ /* Meth 2 | <----- X_sav 16 ms ----------> | ^xfp_fx ptr | */
+ /* Meth2 ,prevBfi=1 | | <-12.25(forTDC),3.75(PLC2)->| */ /*the part used by PhECU is 3.75ms */
+ /* ConcealMethod 2 |<- <10ms ->| */
+ int max_plocs = DYN_MAX_PLOCS(samplerate);
+ plcAd = balloc(decoder, &size, sizeof(*setup->plcAd));
+ PhECU_f0est = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_f0est) * max_plocs);
+ PhECU_plocs = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_plocs) * max_plocs);
+#ifdef ENABLE_HR_MODE
+ q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * max_len);
+#else
+ q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * MIN(max_len, MAX_BW));
+#endif
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+/* longterm_analysis_counter_max = PLC_LONGTERM_ANALYSIS_MS * (100.0f / 25.0f);*/
+/* assert(longterm_analysis_counter_max == (PLC_LONGTERM_ANALYSIS_MS * (100 /25))); */ /* test integer division for compatibility */
+/* longterm_analysis_counter_max_bytebuffer = floor(longterm_analysis_counter_max / 30.0); */
+/* assert(longterm_analysis_counter_max_bytebuffer == (longterm_analysis_counter_max / 30)); */ /* test integer division for compatibility */
+
+/* longterm_analysis_counter_max = (longterm_analysis_counter_max_bytebuffer+1) * 30; */
+
+ longterm_analysis_counter_max = plc_fadeout_param_maxlen[0];
+ longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0];
+
+ plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(Word32) * longterm_analysis_counter_max_bytebuffer);
+ plc_longterm_advc_ns = balloc(decoder, &size, sizeof(Word32) * longterm_analysis_counter_max_bytebuffer);
+#endif
+
+ if (decoder)
+ {
+ decoder->channel_setup[ch] = setup;
+ setup->ltpf_mem_x = ltpf_mem_x;
+ setup->ltpf_mem_y = ltpf_mem_y;
+ setup->stDec_ola_mem_fx = stDec_ola_mem_fx;
+ setup->q_old_res_fx = q_old_res_fx;
+#if defined(ENABLE_PC)
+ setup->q_old_d_fx = q_old_d_fx;
+#else
+ setup->q_old_d_fx = sharedBuf;
+#endif
+ setup->plcAd = plcAd;
+ }
+ if (decoder && plcAd)
+ {
+#ifdef ENABLE_HR_MODE
+ if (fs_idx > 4)
+ {
+ fs_idx = 4;
+ }
+#endif
+
+ setup->plcAd->x_old_tot_fx = &sharedBuf[q_old_len];
+ setup->plcAd->PhECU_f0est = PhECU_f0est;
+ setup->plcAd->PhECU_xfp_fx = &(setup->plcAd->x_old_tot_fx[x_old_len-LprotSzPtr[fs_idx]]); /* point to the last 16ms of the x_old_tot_fx */
+ setup->plcAd->PhECU_X_sav_fx = sharedBuf; /* reuse of lprot(=num_FsByResQ0[fs_idx]) values from this point fwd, i.e beyond the end of q_old_fx */
+ setup->plcAd->PhECU_plocs = PhECU_plocs;
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ setup->plcAd->longterm_analysis_counter_max = longterm_analysis_counter_max;
+ setup->plcAd->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer;
+
+ setup->plcAd->plc_longterm_advc_tdc = plc_longterm_advc_tdc;
+ setup->plcAd->plc_longterm_advc_ns = plc_longterm_advc_ns;
+#endif
+ }
+ }
+
+ return (int)size;
+}
+
+LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ )
+{
+ int ch = 0;
+
+ memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels, plc_mode));
+ alloc_decoder(decoder, samplerate, channels);
+
+#ifdef ENABLE_HR_MODE
+ decoder->hrmode = hrmode != 0;
+#endif
+
+ decoder->fs = CODEC_FS(samplerate);
+ decoder->fs_out = samplerate;
+ decoder->fs_idx = FS2FS_IDX(decoder->fs);
+ decoder->channels = channels;
+ decoder->frame_dms = 100;
+ decoder->plcMeth = plc_mode;
+ {
+ decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx];
+ }
+ decoder->ltpf_mem_x_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 11)) - 2;
+ decoder->ltpf_mem_y_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 18678) - 1, 5)) + 1 +
+ extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 12));
+
+ set_dec_frame_params(decoder);
+
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ DecSetup *setup = decoder->channel_setup[ch];
+ setup->plc_damping = 32767;
+ setup->ltpf_mem_scale_fac_idx = -1;
+ move16();
+
+ setup->pc_seed = 24607;
+ setup->ns_seed = 24607;
+ setup->ns_cum_alpha = 32767;
+
+ int i = 0;
+ /* 0 = 0kHz 1= 8kHz, 2= 16 kHz 3= 24 , 4 = 32 5=40 6=48kHz */
+#if (PHECU_XFP_LA == 0)
+ Word16 oneMsTab_LA[5] = {0, 0, 0, 0, 0};
+#else
+# if (PHECU_XFP_LA == 4)
+ Word16 oneMsTab_LA[7] = {0 /*unused*/, 2, 4, 6, 8, 10 /*unused*/, 12};
+# else
+ Word16 oneMsTab_LA[7] = {0 /*unused*/, 8, 16, 24, 32, 40 /*unused*/, 48};
+# endif
+#endif
+ Word16 oneMsTab[5] = {8, 16, 24, 32, 48};
+
+ setup->plcAd->stab_fac = 32767;
+ setup->plcAd->tdc_seed = 24607;
+ setup->plcAd->tdc_preemph_fac = plc_preemph_fac[decoder->fs_idx];
+ setup->plcAd->tdc_lpc_order = 16;
+ setup->plcAd->PhECU_fs_idx_fx =
+ mult(decoder->frame_length,
+ (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */
+ /* idx=frame/80, 0=8kHZ, 1=16kHz, 2=24 kHz, 3=32 kHz 5=*, 4=48 */
+
+ setup->plcAd->max_len_pcm_plc = DYN_MAX_LEN_PCM_PLC(decoder->fs);
+
+ if ((decoder->hrmode == 0) && (samplerate <= 48000))
+ {
+ setup->plcAd->PhECU_frame_ms = (Word16)(
+ decoder->frame_dms * 0.1); /* needed in PLCUpdate and PLC main functions, adjusted in first frame */
+ setup->plcAd->PhECU_seed_fx = 21845;
+ setup->plcAd->PhECU_LprotOrg_fx =
+ shl_pos(oneMsTab[setup->plcAd->PhECU_fs_idx_fx], 4); /* 16 *1ms = 1.6 *framelength */
+ setup->plcAd->PhECU_Lprot_fx = setup->plcAd->PhECU_LprotOrg_fx;
+ setup->plcAd->PhECU_LA = oneMsTab_LA[setup->plcAd->PhECU_fs_idx_fx];
+ setup->plcAd->PhECU_whr_tot_taper = sub(setup->plcAd->PhECU_Lprot_fx, decoder->frame_length); /* 3+3 ms */
+ setup->plcAd->PhECU_whr_tot_flat = decoder->frame_length; /* 10 ms */
+ setup->plcAd->PhECU_LDWIN_OLAP = shr_pos(decoder->frame_length, 2); /* 2.5 ms */
+ setup->plcAd->max_lprot = DYN_MAX_LPROT(decoder->fs);
+ setup->plcAd->max_plocs = DYN_MAX_PLOCS(decoder->fs);
+ setup->plcAd->PhECU_margin_xfp = 0;
+ setup->plcAd->PhECU_L_oold_xfp_w_E_fx = LTOT_MIN_MAN;
+ setup->plcAd->PhECU_L_old_xfp_w_E_fx = LTOT_MIN_MAN;
+
+ setup->plcAd->PhECU_oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL;
+ setup->plcAd->PhECU_old_xfp_w_E_exp_fx = LTOT_INIT_FLAG;
+
+ setup->plcAd->PhECU_oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL;
+ setup->plcAd->PhECU_old_Ltot_exp_fx = LTOT_INIT_FLAG;
+
+
+ for (i = 0; i < MAX_LGW; i++)
+ {
+ setup->plcAd->PhECU_oold_grp_shape_fx[i] =
+ GRP_SHAPE_INIT; /* negative value will be replaced in very first calculation */
+ setup->plcAd->PhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT;
+ }
+ /* t_adv=ctrl.FRAME/2 + ctrl.PhECU.LprotOrg/2 - ctrl.PhECU.LA + LDWIN_OLAP/2; */
+ i = add(add(decoder->frame_length, setup->plcAd->PhECU_LprotOrg_fx), setup->plcAd->PhECU_LDWIN_OLAP);
+ setup->plcAd->PhECU_t_adv = sub(shr_pos(i, 1), setup->plcAd->PhECU_LA);
+
+ for (i = 0; i < MAX_LGW; i++)
+ {
+ setup->plcAd->PhECU_mag_chg_1st[i] = 32767;
+ }
+ setup->plcAd->PhECU_beta_mute = 16384;
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ setup->plcAd->PhECU_nonpure_tone_flag = -1;
+#endif
+ }
+ }
+
+ lc3plus_dec_set_ep_enabled(decoder, 0);
+ return LC3PLUS_OK;
+}
+
+/* set frame config params */
+void set_dec_frame_params(LC3PLUS_Dec *decoder)
+{
+# ifdef CR8_G_ADD_75MS
+ Word16 tmp = 0;
+# endif
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ Word16 n;
+#endif
+
+ decoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 20972), 6)); /* fs * 0.01*2^6 */
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ decoder->BW_cutoff_bits = 0;
+ }
+#endif
+
+ SWITCH (decoder->frame_dms)
+ {
+ case 25:
+ decoder->frame_length = shr_pos(decoder->frame_length, 2);
+ decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[decoder->fs_idx];
+ decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes);
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx];
+ decoder->bands_offset = bands_offset_2_5ms_HR[decoder->fs_idx - 4];
+ decoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[decoder->fs_idx - 4];
+ decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx];
+ decoder->yLen = decoder->frame_length;
+ }
+ else
+#endif
+ {
+ decoder->bands_number = bands_number_2_5ms[decoder->fs_idx];
+ decoder->bands_offset = bands_offset_2_5ms[decoder->fs_idx];
+ decoder->W_fx = LowDelayShapes_n960_2_5ms[decoder->fs_idx];
+ decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx];
+ decoder->yLen = s_min(MAX_BW >> 2, decoder->frame_length);
+ }
+
+ if (decoder->fs_idx == 0)
+ {
+ int ch;
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ DecSetup *setup = decoder->channel_setup[ch];
+ if (setup->plcAd != NULL)
+ {
+ setup->plcAd->tdc_lpc_order = 8;
+ }
+ }
+ }
+ BREAK;
+ case 50:
+ decoder->frame_length = shr_pos(decoder->frame_length, 1);
+ decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[decoder->fs_idx];
+ decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes);
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ decoder->bands_offset = bands_offset_5ms_HR[decoder->fs_idx - 4];
+ decoder->W_fx = LowDelayShapes_n960_HRA_5ms[decoder->fs_idx - 4];
+ decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx];
+ decoder->yLen = decoder->frame_length;
+ decoder->bands_number = bands_number_5ms[decoder->fs_idx];
+ }
+ else
+#endif
+ {
+ decoder->bands_offset = bands_offset_5ms[decoder->fs_idx];
+ decoder->W_fx = LowDelayShapes_n960_5ms[decoder->fs_idx];
+ decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx];
+ decoder->yLen = s_min(MAX_BW >> 1, decoder->frame_length);
+ decoder->bands_number = bands_number_5ms[decoder->fs_idx];
+ }
+ BREAK;
+
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ tmp = shr_pos(decoder->frame_length, 2);
+ decoder->frame_length = add(tmp, add(tmp, tmp));
+ decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[decoder->fs_idx];
+ decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes);
+# ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ decoder->bands_offset = bands_offset_7_5ms_HR[decoder->fs_idx - 4];
+ decoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[decoder->fs_idx - 4];
+ decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx];
+ decoder->yLen = decoder->frame_length;
+ decoder->bands_number = bands_number_7_5ms[decoder->fs_idx];
+ }
+ else
+# endif
+ {
+ decoder->bands_offset = bands_offset_7_5ms[decoder->fs_idx];
+ decoder->W_fx = LowDelayShapes_n960_7_5ms[decoder->fs_idx];
+ decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx];
+ decoder->yLen = s_min((MAX_BW >> 2) * 3, decoder->frame_length);
+ decoder->bands_number = bands_number_7_5ms[decoder->fs_idx];
+ }
+ BREAK;
+# endif
+
+ case 100:
+ decoder->la_zeroes = LowDelayShapes_n960_la_zeroes[decoder->fs_idx];
+ decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes);
+ decoder->bands_number = 64;
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ decoder->bands_offset = bands_offset_HR[decoder->fs_idx - 4];
+ decoder->W_fx = LowDelayShapes_n960_HRA[decoder->fs_idx - 4];
+ decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx];
+ decoder->yLen = decoder->frame_length;
+ }
+ else
+#endif
+ {
+ decoder->W_fx = LowDelayShapes_n960[decoder->fs_idx];
+ decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx];
+ decoder->bands_offset = bands_offset[decoder->fs_idx];
+ decoder->yLen = s_min(MAX_BW, decoder->frame_length);
+ }
+ BREAK;
+ }
+
+ {
+ int ch;
+ for (ch = 0; ch < decoder->channels; ch++)
+ {
+ DecSetup *setup = decoder->channel_setup[ch];
+ if (setup->plcAd != NULL)
+ { /*only set if plcAd was actually allocated */
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ setup->plcAd->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1];
+ setup->plcAd->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1];
+
+#endif
+ setup->plcAd->PhECU_frame_ms = (Word16)(
+ decoder->frame_dms *
+ 0.1); /* needed in processPLCupdate_fx(), now set properly set in first frame /second time */
+ }
+ }
+ }
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ FOR (n=0; n < PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms;n++){
+ decoder->alpha_type_2_table[n] = type_2_fadeout_fx(n, decoder->frame_dms);
+ }
+#endif
+}
+
+LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes)
+{
+ int tmp = 0, totalBits = 0;
+ int channel_bytes = 0;
+ int minBytes, maxBytes;
+
+ DecSetup *setup = decoder->channel_setup[ch];
+ channel_bytes = nBytes;
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode)
+ {
+ SWITCH (decoder->frame_dms)
+ {
+ case 25:
+ maxBytes = 210;
+ minBytes = MIN_NBYTES;
+ BREAK;
+ case 50:
+ maxBytes = 375;
+ minBytes = MIN_NBYTES;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ maxBytes = 625;
+ minBytes = MIN_NBYTES;
+ BREAK;
+#endif
+ case 100:
+ maxBytes = 625;
+ minBytes = MIN_NBYTES;
+ BREAK;
+ default: return LC3PLUS_HRMODE_ERROR;
+ }
+ }
+ else
+#endif
+ {
+ minBytes = MIN_NBYTES;
+ maxBytes = MAX_NBYTES_100;
+ }
+
+ if (channel_bytes < minBytes || channel_bytes > maxBytes)
+ {
+ return LC3PLUS_NUMBYTES_ERROR;
+ }
+
+ setup->targetBytes = channel_bytes;
+ move16();
+ setup->total_bits = shl(setup->targetBytes, 3);
+ setup->enable_lpc_weighting = (setup->total_bits < 480);
+ setup->quantizedGainOff =
+ -(s_min(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1));
+ tmp = DEPR_i_mult(80, decoder->fs_idx);
+
+#ifdef ENABLE_HR_MODE
+ if (decoder->hrmode && decoder->fs_idx == 5)
+ {
+ setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181);
+ }
+#endif
+
+ totalBits = setup->total_bits;
+
+
+ SWITCH (decoder->frame_dms)
+ {
+ case 25:
+ setup->enable_lpc_weighting = 0;
+ /* total_bits * 2.4 */
+ totalBits = extract_l(L_shr(L_mult0(19661, setup->total_bits), 13));
+ BREAK;
+ case 50:
+ setup->enable_lpc_weighting = setup->total_bits < 240;
+ totalBits = sub(DEPR_i_mult(setup->total_bits, 2), 160);
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ setup->enable_lpc_weighting = setup->total_bits < 360;
+ totalBits = L_shr(L_mult0(10923, setup->total_bits), 13);
+ BREAK;
+# endif
+ case 100:
+ BREAK;
+ }
+
+
+ if (sub(totalBits, add(320, tmp)) < 0)
+ {
+ setup->ltpf_scale_fac_idx = 0;
+ move16();
+ }
+ else if (sub(totalBits, add(400, tmp)) < 0)
+ {
+ setup->ltpf_scale_fac_idx = 1;
+ move16();
+ }
+ else if (sub(totalBits, add(480, tmp)) < 0)
+ {
+ setup->ltpf_scale_fac_idx = 2;
+ move16();
+ }
+ else if (sub(totalBits, add(560, tmp)) < 0)
+ {
+ setup->ltpf_scale_fac_idx = 3;
+ move16();
+ }
+ else
+ {
+ setup->ltpf_scale_fac_idx = -1;
+ move16();
+ }
+
+#ifdef ENABLE_HR_MODE
+ /* No LTPF in hrmode */
+ if (decoder->hrmode)
+ {
+ setup->ltpf_scale_fac_idx = -1;
+ move16();
+ }
+#endif
+
+ return LC3PLUS_OK;
+}
+
diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c36163d3a8e906fbd264c16014efa1b829cda2d
--- /dev/null
+++ b/lib_lc3plus/setup_dec_lc3.h
@@ -0,0 +1,185 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef SETUP_DEC_LC3_H
+#define SETUP_DEC_LC3_H
+
+#include "constants.h"
+
+typedef struct
+{
+ Word16 *x_old_tot_fx; /* MAX_LEN_PCM_PLC_TOT */
+ Word32 *PhECU_f0est; /* MAX_PLOCS interpolated plocs */
+ Word16 *PhECU_xfp_fx; /* MAX_LPROT */
+ Word16 *PhECU_X_sav_fx; /* MAX_LPROT */
+ Word16 *PhECU_plocs; /* MAX_PLOCS */
+ Word16 *PhECU_fg_wintaper; /* MDCT_MEM_LEN_MAX */
+ Word16 *PhECU_win_pre_tda; /* MAX_WIN_PRE_TDA */
+ Word32 tdc_gain_c;
+ Word16 stab_fac;
+ Word16 tdc_fract;
+ Word16 tdc_seed;
+ Word16 tdc_preemph_fac;
+ Word16 tdc_lpc_order;
+ Word16 cum_fflcAtten;
+ Word16 harmonicBuf_fx[MAX_PITCH] ALIGN_BUFFER_STRUCT;
+ Word16 harmonicBuf_Q;
+ Word16 synthHist_fx[M] ALIGN_BUFFER_STRUCT;
+ Word16 cum_fading_slow;
+ Word16 cum_fading_fast;
+ Word16 PhECU_LprotOrg_fx; /* needed to change the Prot size adaptively */
+ Word16 PhECU_Lprot_fx;
+ Word16 PhECU_fs_idx_fx;
+ Word16 PhECU_frame_ms; /* needed in PLC_Update and PLCMain functons*/
+ Word16 PhECU_seed_fx;
+ Word16 PhECU_xfp_exp_fx;
+ Word16 PhECU_time_offs;
+ Word16 PhECU_X_savQ_fx;
+ Word16 PhECU_num_plocs;
+ Word16 PhECU_f0hzLtpBinQ7; /* ltp F0 in bins if available */
+ Word16 PhECU_short_flag_prev;
+ Word16 PhECU_whr_tot_taper;
+ Word16 PhECU_whr_tot_flat;
+ Word16 PhECU_LDWIN_OLAP;
+ Word16 PhECU_LA;
+ Word16 PhECU_t_adv;
+ Word16 PhECU_beta_mute;
+ Word16 norm_corrQ15_fx;
+ Word16 q_fx_old_exp;
+ Word16 max_len_pcm_plc;
+ Word16 max_lprot;
+ Word16 max_plocs;
+
+ /* Word32 L_tot W_energy sum exponent */
+ Word16 PhECU_oold_Ltot_exp_fx;
+ Word16 PhECU_old_Ltot_exp_fx;
+ Word32 PhECU_L_oold_xfp_w_E_fx;
+ Word32 PhECU_L_old_xfp_w_E_fx;
+ Word16 PhECU_oold_xfp_w_E_exp_fx; /* input Word16 xfp exponnet */
+ Word16 PhECU_old_xfp_w_E_exp_fx;
+ Word16 PhECU_oold_grp_shape_fx[MAX_LGW] ALIGN_BUFFER_STRUCT;
+ Word16 PhECU_old_grp_shape_fx[MAX_LGW] ALIGN_BUFFER_STRUCT;
+ Word16 PhECU_margin_xfp;
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 PhECU_nonpure_tone_flag; /* non-pure single tone indicator state */
+#endif
+ Word16 PhECU_mag_chg_1st[MAX_LGW] ALIGN_BUFFER_STRUCT;
+ Word16 PhECU_Xavg[MAX_LGW] ALIGN_BUFFER_STRUCT;
+ Word16 old_scf_q[M] ALIGN_BUFFER_STRUCT;
+ Word16 old_old_scf_q[M] ALIGN_BUFFER_STRUCT;
+ Word16 tdc_A[M + 1] ALIGN_BUFFER_STRUCT;
+ /* for now 20 ms saved Q14 or ptr to a combined ifft win and MDCT preTDA synthesis window 16 ms */
+
+#ifdef CR8_A_PLC_FADEOUT_TUNING
+ Word16 longterm_counter_plcTdc;
+# ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER
+ Word16 longterm_counter_plcPhaseEcu;
+# endif
+ Word16 longterm_counter_plcNsAdv;
+ Word16 longterm_analysis_counter_max; /* Maximum longterm frames number */
+ Word16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */
+ Word32 *plc_longterm_advc_tdc;
+ Word32 *plc_longterm_advc_ns;
+ UWord8 plc_fadeout_type;
+ Word16 overall_counter;
+ Word8 longterm_counter_byte_position;
+ Word8 longterm_counter_bit_position;
+#endif
+} AplcSetup;
+
+/* Channel state and bitrate-derived values go in this struct */
+typedef struct
+{
+ Word16 *ltpf_mem_x; /* LTPF_MEM_X_LEN */
+ Word16 *ltpf_mem_y; /* LTPF_MEM_Y_LEN */
+#ifdef ENABLE_HR_MODE
+ Word32 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */
+#else
+ Word16 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */
+#endif
+ AplcSetup *plcAd;
+ Word16 * q_old_d_fx; /* MAX_BW */
+ Word16 q_old_fx_exp;
+ Word16 ns_seed;
+ Word16 ns_cum_alpha;
+ Word16 pc_nbLostFramesInRow;
+ Word16 pc_seed;
+ Word16 *q_old_res_fx;
+ Word16 q_old_res_fx_exp;
+ Word16 prev_gg;
+ Word16 prev_gg_e;
+ Word16 prev_BW_cutoff_idx_nf;
+ Word16 prev_fac_ns_fx;
+ Word16 total_bits;
+ Word16 enable_lpc_weighting;
+ Word16 stDec_ola_mem_fx_exp;
+ Word16 targetBytes;
+ Word16 ltpf_mem_e;
+ Word16 ltpf_mem_pitch_int;
+ Word16 ltpf_mem_pitch_fr;
+ Word16 ltpf_mem_gain;
+ Word16 ltpf_mem_active;
+ Word16 ltpf_scale_fac_idx;
+ Word16 ltpf_mem_scale_fac_idx;
+ Word16 quantizedGainOff;
+ Word16 prev_bfi;
+ Word16 prev_prev_bfi;
+ Word16 concealMethod;
+ Word16 nbLostFramesInRow;
+ Word16 plc_damping;
+ Word16 last_size;
+#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH
+ Word32 rel_pitch_change;
+#endif
+} DecSetup;
+
+/* Constants and sampling rate derived values go in this struct */
+struct LC3PLUS_Dec
+{
+ DecSetup * channel_setup[MAX_CHANNELS];
+#ifdef ENABLE_HR_MODE
+ const Word32 *W_fx;
+#else
+ const Word16 *W_fx;
+#endif
+ const Word16 *bands_offset;
+ Word32 fs; /* sampling rate, 44.1 maps to 48 */
+ Word32 fs_out; /* output sampling rate */
+ Word16 fs_idx; /* sampling rate index */
+ Word16 frame_length; /* sampling rate index */
+ Word16 channels; /* number of channels */
+ Word16 plcMeth; /* PLC method for all channels */
+ Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/
+ Word16 last_size; /* size of last frame, without error protection */
+ Word16 ep_enabled; /* error protection enabled */
+ Word16 error_report; /* corrected errors in last frame or -1 on error */
+
+ Word16 n_pccw;
+ Word16 be_bp_left;
+ Word16 be_bp_right;
+ Word16 n_pc;
+ Word16 m_fec;
+ Word16 epmr;
+ Word16 combined_channel_coding;
+
+ Word16 yLen;
+ Word16 W_size;
+ Word16 la_zeroes;
+ Word16 stDec_ola_mem_fx_len;
+ Word16 bands_number;
+ Word16 ltpf_mem_x_len;
+ Word16 ltpf_mem_y_len;
+ Word16 BW_cutoff_bits;
+ Word16 hrmode;
+#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR
+ Word16 alpha_type_2_table[80];/* PLC_FADEOUT_TYPE_1_IN_MS*10/25 */
+#endif
+};
+
+#endif
diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e20912bb078e46dac98e383414e7a43ff17a8dc
--- /dev/null
+++ b/lib_lc3plus/setup_enc_lc3.c
@@ -0,0 +1,760 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+#include "setup_enc_lc3.h"
+
+/* if encoder is null only size is reported */
+int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels)
+{
+ int ch = 0;
+ size_t size = sizeof(LC3PLUS_Enc);
+ void * mdct_mem32 = NULL, *stEnc_mdct_mem = NULL;
+
+ for (ch = 0; ch < channels; ch++)
+ {
+ EncSetup *setup = balloc(encoder, &size, sizeof(EncSetup));
+ mdct_mem32 = balloc(encoder, &size, sizeof(*setup->mdct_mem32) * DYN_MAX_MDCT_LEN(samplerate));
+ stEnc_mdct_mem = balloc(encoder, &size, sizeof(*setup->stEnc_mdct_mem) * DYN_MAX_MDCT_LEN(samplerate));
+ if (encoder)
+ {
+ encoder->channel_setup[ch] = setup;
+ setup->mdct_mem32 = mdct_mem32;
+ setup->stEnc_mdct_mem = stEnc_mdct_mem;
+ }
+ }
+
+ return (int)size;
+}
+
+LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels
+#ifdef ENABLE_HR_MODE
+ , int hrmode
+#endif
+ , int32_t lfe_channel_array[]
+ )
+{
+ int ch = 0;
+
+ memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels));
+ alloc_encoder(encoder, samplerate, channels);
+
+ encoder->fs = CODEC_FS(samplerate);
+ encoder->fs_in = samplerate;
+ encoder->fs_idx = FS2FS_IDX(encoder->fs);
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->fs_idx > 4)
+ {
+ encoder->fs_idx = 5;
+ }
+ encoder->hrmode = hrmode != 0;
+# endif
+
+ encoder->channels = channels;
+ encoder->frame_dms = 100;
+ encoder->envelope_bits = 38;
+ encoder->global_gain_bits = 8;
+ encoder->noise_fac_bits = 3;
+ encoder->r12k8_mem_in_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 9));
+ encoder->r12k8_mem_out_len = 24;
+ encoder->epmr = LC3PLUS_EPMR_ZERO;
+ encoder->bw_ctrl_active = 0;
+ encoder->bandwidth = L_shr_pos(encoder->fs, 1);
+ encoder->bandwidth_preset = L_shr_pos(encoder->fs, 1);
+
+ for (ch = 0; ch < encoder->channels; ch++)
+ {
+ encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0;
+ }
+
+
+ for (ch = 0; ch < encoder->channels; ch++)
+ {
+ encoder->channel_setup[ch]->x_exp = 15;
+ encoder->channel_setup[ch]->resamp_exp = 17;
+ }
+
+ set_enc_frame_params(encoder);
+
+ return lc3plus_enc_set_ep_mode(encoder, LC3PLUS_EP_OFF); /* also calls update_enc_bitrate */
+}
+
+/* set frame config params */
+void set_enc_frame_params(LC3PLUS_Enc *encoder)
+{
+#ifdef CR8_G_ADD_75MS
+# ifdef ENABLE_075_DMS_MODE
+ Word16 tmp;
+# endif
+#endif
+
+ encoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 6)); /* fs * 0.01*2^6 */
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ encoder->BW_cutoff_bits = 0;
+ }
+ else
+# endif
+ {
+ encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx];
+ }
+
+ SWITCH (encoder->frame_dms)
+ {
+ case 25:
+ encoder->frame_length = shr_pos(encoder->frame_length, 2);
+ encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[encoder->fs_idx];
+ encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes);
+ encoder->nSubdivisions = 2;
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2);
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx];
+ encoder->bands_offset = bands_offset_2_5ms_HR[encoder->fs_idx - 4];
+ encoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[encoder->fs_idx - 4];
+ encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx];
+ encoder->yLen = encoder->frame_length;
+ }
+ else
+# endif
+ {
+ encoder->yLen = s_min(MAX_BW >> 2, encoder->frame_length);
+ encoder->W_fx = LowDelayShapes_n960_2_5ms[encoder->fs_idx];
+ encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx];
+ encoder->bands_number = bands_number_2_5ms[encoder->fs_idx];
+ encoder->bands_offset = bands_offset_2_5ms[encoder->fs_idx];
+ encoder->near_nyquist_index = encoder->bands_number - 2;
+ encoder->near_nyquist_flag = 0;
+ }
+
+ BREAK;
+ case 50:
+ encoder->frame_length = shr_pos(encoder->frame_length, 1);
+ encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[encoder->fs_idx];
+ encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes);
+ encoder->nSubdivisions = 2;
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 1);
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ encoder->bands_offset = bands_offset_5ms_HR[encoder->fs_idx - 4];
+ encoder->W_fx = LowDelayShapes_n960_HRA_5ms[encoder->fs_idx - 4];
+ encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx];
+ encoder->yLen = encoder->frame_length;
+ encoder->bands_number = bands_number_5ms[encoder->fs_idx];
+ }
+ else
+# endif
+ {
+ encoder->yLen = s_min(MAX_BW >> 1, encoder->frame_length);
+ encoder->W_fx = LowDelayShapes_n960_5ms[encoder->fs_idx];
+ encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx];
+ encoder->bands_number = bands_number_5ms[encoder->fs_idx];
+ encoder->bands_offset = bands_offset_5ms[encoder->fs_idx];
+ encoder->near_nyquist_index = encoder->bands_number - 3;
+ encoder->near_nyquist_flag = 0;
+ }
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN;
+ BREAK;
+
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ tmp = shr_pos(encoder->frame_length, 2);
+ encoder->frame_length = add(tmp, add(tmp, tmp));
+ encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[encoder->fs_idx];
+ encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes);
+ encoder->bands_number = bands_number_7_5ms[encoder->fs_idx];
+ encoder->nSubdivisions = 3;
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN;
+ encoder->attdec_nblocks = 3;
+ encoder->attdec_damping = 9830;
+ encoder->attdec_hangover_thresh = 1;
+ encoder->r12k8_mem_out_len = 44;
+ encoder->near_nyquist_index = encoder->bands_number - 4;
+ encoder->near_nyquist_flag = 0;
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ encoder->yLen = encoder->frame_length;
+ encoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[encoder->fs_idx - 4];
+ encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx];
+ encoder->bands_number = bands_number_7_5ms[encoder->fs_idx];
+ encoder->bands_offset = bands_offset_7_5ms_HR[encoder->fs_idx - 4];
+ }
+ else
+# endif
+ {
+ encoder->yLen = s_min((MAX_BW >> 2) * 3, encoder->frame_length);
+ encoder->W_fx = LowDelayShapes_n960_7_5ms[encoder->fs_idx];
+ encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx];
+ encoder->bands_number = bands_number_7_5ms[encoder->fs_idx];
+ encoder->bands_offset = bands_offset_7_5ms[encoder->fs_idx];
+ }
+ BREAK;
+# endif
+
+ case 100:
+ encoder->la_zeroes = LowDelayShapes_n960_la_zeroes[encoder->fs_idx];
+ encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes);
+ encoder->bands_number = 64;
+ encoder->nSubdivisions = 3;
+ encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN;
+ encoder->attdec_nblocks = 4;
+ encoder->attdec_damping = 16384;
+ encoder->attdec_hangover_thresh = 2;
+ encoder->near_nyquist_index = encoder->bands_number - 2;
+ encoder->near_nyquist_flag = 0;
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ encoder->bands_offset = bands_offset_HR[encoder->fs_idx - 4];
+ encoder->W_fx = LowDelayShapes_n960_HRA[encoder->fs_idx - 4];
+ encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx];
+ encoder->yLen = encoder->frame_length;
+ }
+ else
+# endif
+ {
+ encoder->yLen = s_min(MAX_BW, encoder->frame_length);
+ encoder->W_fx = LowDelayShapes_n960[encoder->fs_idx];
+ encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx];
+ encoder->bands_offset = bands_offset[encoder->fs_idx];
+ }
+ BREAK;
+ }
+}
+
+/* change encoder bitrate */
+LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate)
+{
+ int ch = 0;
+ int totalBytes = 0, maxBR = 0, minBR = 0, max_bytes = 0;
+ int channel_bytes = 0;
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ switch (encoder->frame_dms)
+ {
+ case 25:
+ maxBR = 672000;
+ if (encoder->fs == 48000)
+ {
+ minBR = MIN_BR_25MS_48KHZ_HR;
+ }
+ else if (encoder->fs == 96000)
+ {
+ minBR = MIN_BR_25MS_96KHZ_HR;
+ }
+ else
+ {
+ return LC3PLUS_HRMODE_ERROR;
+ }
+ break;
+ case 50:
+ maxBR = 600000;
+ if (encoder->fs == 48000)
+ {
+ minBR = MIN_BR_50MS_48KHZ_HR;
+ }
+ else if (encoder->fs == 96000)
+ {
+ minBR = MIN_BR_50MS_96KHZ_HR;
+ }
+ else
+ {
+ return LC3PLUS_HRMODE_ERROR;
+ }
+ break;
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ maxBR = 500000;
+ if (encoder->fs == 48000) {minBR = MIN_BR_075DMS_48KHZ_HR;}
+ else if (encoder->fs == 96000) {minBR = MIN_BR_075DMS_96KHZ_HR;}
+ else {return LC3PLUS_HRMODE_ERROR;}
+ BREAK;
+# endif
+ case 100:
+ maxBR = 500000;
+ if (encoder->fs == 48000)
+ {
+ minBR = MIN_BR_100MS_48KHZ_HR;
+ }
+ else if (encoder->fs == 96000)
+ {
+ minBR = MIN_BR_100MS_96KHZ_HR;
+ }
+ else
+ {
+ return LC3PLUS_HRMODE_ERROR;
+ }
+ break;
+ default: return LC3PLUS_HRMODE_ERROR;
+ }
+ }
+ else
+ {
+ minBR = (MIN_NBYTES << 3);
+ maxBR = MAX_BR;
+
+ switch (encoder->frame_dms)
+ {
+ case 25:
+ minBR = MIN_BR_025DMS;
+ maxBR = MAX_BR;
+ BREAK;
+ case 50:
+ minBR = MIN_BR_050DMS;
+ maxBR = MAX_BR;
+ /* have additional limitations for 5.0ms */
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_050DMS_NB; BREAK;
+# endif
+ default: BREAK;
+ }
+ BREAK;
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ minBR = MIN_BR_075DMS;
+ maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms
+ /* have additional limitations for 7.5ms */
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK;
+# endif
+# ifdef SUBSET_WB
+ case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK;
+# endif
+# ifdef SUBSET_SSWB
+ case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK;
+# endif
+ default: BREAK;
+ }
+ BREAK;
+# endif
+ case 100:
+ /* have additional limitations for 10ms */
+ minBR = MIN_BR_100DMS;
+ maxBR = MAX_BR;
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK;
+# endif
+# ifdef SUBSET_WB
+ case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK;
+# endif
+# ifdef SUBSET_SSWB
+ case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK;
+# endif
+ default: maxBR = MAX_BR; BREAK;
+ }
+ BREAK;
+ default: return LC3PLUS_FRAMEMS_ERROR;
+ }
+
+ /* 441/480 in Q31 and 1000/75 in Q23 */
+ if (encoder->fs_in == 44100)
+ {
+ minBR = Mpy_32_32_lc3plus(minBR, 1973000602);
+ maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602);
+ }
+ }
+#else /* ENABLE_HR_MODE */
+ minBR = (MIN_NBYTES << 3);
+ maxBR = MAX_BR;
+
+ switch (encoder->frame_dms)
+ {
+ case 25:
+ minBR = MIN_BR_025DMS;
+ maxBR = MAX_BR;
+ BREAK;
+ case 50:
+ minBR = MIN_BR_050DMS;
+ maxBR = MAX_BR;
+ /* have additional limitations for 5.0ms */
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_050DMS_NB; BREAK;
+# endif
+ default: BREAK;
+ }
+ BREAK;
+# ifdef CR8_G_ADD_75MS
+ case 75:
+ minBR = MIN_BR_075DMS;
+ maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms
+ /* have additional limitations for 7.5ms */
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK;
+# endif
+# ifdef SUBSET_WB
+ case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK;
+# endif
+# ifdef SUBSET_SSWB
+ case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK;
+# endif
+ default: BREAK;
+ }
+ BREAK;
+# endif
+ case 100:
+ /* have additional limitations for 10ms */
+ minBR = MIN_BR_100DMS;
+ maxBR = MAX_BR;
+ SWITCH (encoder->fs_in)
+ {
+# ifdef SUBSET_NB
+ case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK;
+# endif
+# ifdef SUBSET_WB
+ case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK;
+# endif
+# ifdef SUBSET_SSWB
+ case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK;
+# endif
+ default: maxBR = MAX_BR; BREAK;
+ }
+ BREAK;
+ default: return LC3PLUS_FRAMEMS_ERROR;
+ }
+
+ /* 441/480 in Q31 and 1000/75 in Q23 */
+ if (encoder->fs_in == 44100)
+ {
+ minBR = Mpy_32_32_lc3plus(minBR, 1973000602);
+ maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602);
+ }
+#endif /* ENABLE_HR_MODE */
+
+ minBR *= encoder->channels;
+ maxBR *= encoder->channels;
+
+ if (bitrate < minBR || bitrate > maxBR)
+ {
+ return LC3PLUS_BITRATE_ERROR;
+ }
+
+ encoder->bitrate = bitrate;
+ encoder->lc3_br_set = 1;
+
+ /* move stuff to encoder->channel_setup */
+
+ encoder->combined_channel_coding = 0;
+ if (encoder->channels > 1 && encoder->epmode)
+ {
+ if (encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in) <= 160)
+ {
+ encoder->combined_channel_coding = 1;
+ }
+ }
+
+ if (encoder->epmode > 0)
+ {
+ max_bytes = bitrate * encoder->frame_length / (8 * encoder->fs_in * encoder->channels);
+
+ if (max_bytes < FEC_SLOT_BYTES_MIN || max_bytes > FEC_SLOT_BYTES_MAX)
+ {
+ return LC3PLUS_BITRATE_ERROR;
+ }
+ }
+
+ if (encoder->combined_channel_coding)
+ {
+ totalBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding,
+ bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in));
+
+ encoder->channel_setup[0]->n_pccw =
+ fec_get_n_pccw(bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in), encoder->epmode,
+ encoder->combined_channel_coding);
+
+ encoder->channel_setup[0]->n_pc = fec_get_n_pc(encoder->epmode, encoder->channel_setup[0]->n_pccw,
+ bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in));
+ }
+ else
+ {
+ totalBytes = bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in);
+ }
+
+ for (ch = 0; ch < encoder->channels; ch++)
+ {
+ EncSetup *setup = encoder->channel_setup[ch];
+ channel_bytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels));
+
+ if (encoder->combined_channel_coding)
+ {
+ setup->targetBytes = channel_bytes;
+ }
+ else
+ {
+ setup->targetBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, channel_bytes);
+ setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding);
+ setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes);
+ }
+ /* reduce bandwith to 12kHz if bitrate is low */
+ if (sub(encoder->frame_dms, 100) == 0 &&
+ ((sub(setup->targetBytes, 40) < 0 && L_sub(encoder->fs, 48000) == 0) ||
+ (sub(setup->targetBytes, 36) < 0 && L_sub(encoder->fs, 32000) == 0)))
+ {
+ encoder->bandwidth = L_min(12000, encoder->bandwidth_preset);
+ }
+ else
+ {
+ /* channel with highest index has lowest bitrate.
+ For a second channel with lower targetBytes, bandwidth is overwritten */
+ encoder->bandwidth = encoder->bandwidth_preset;
+ }
+
+ {
+ Word16 tmp;
+
+ SWITCH(encoder->frame_dms)
+ {
+ case 25: tmp = 1; BREAK;
+ case 50: tmp = 2; BREAK;
+ case 75: tmp = 3; BREAK;
+ default : tmp = 4; BREAK;
+ }
+
+ encoder->bw_ctrl_cutoff_bin = L_mult0(Mpy_32_32_lc3plus(encoder->bandwidth, 10737419), tmp); /* bandwidth * frame_dms / 5000 */
+ }
+
+ encoder->bw_index = sub( Mpy_32_32_lc3plus(encoder->bandwidth, 536871), 1); /* (bandwidth / 4000 ) - 1 */
+ switch (encoder->frame_dms)
+ {
+ case 25: max_bytes = MAX_NBYTES_025; break;
+ case 50: max_bytes = MAX_NBYTES_050; break;
+#ifdef ENABLE_075_DMS_MODE
+# ifdef CR8_G_ADD_75MS
+ case 75: max_bytes = MAX_NBYTES_075; BREAK;
+# endif
+#endif
+ case 100: max_bytes = MAX_NBYTES_100; break;
+ }
+#ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ max_bytes = MAX_NBYTES_RED_HR;
+ }
+#endif
+ if (setup->targetBytes < MIN_NBYTES || setup->targetBytes > max_bytes)
+ {
+ return LC3PLUS_BITRATE_ERROR;
+ }
+
+ setup->total_bits = shl(setup->targetBytes, 3);
+ setup->targetBitsInit =
+ sub(setup->total_bits,
+ add(encoder->envelope_bits,
+ add(encoder->global_gain_bits, add(encoder->noise_fac_bits, encoder->BW_cutoff_bits))));
+ setup->targetBitsInit = sub(setup->targetBitsInit, sub(17, norm_s(sub(encoder->yLen, 1))));
+ if (setup->total_bits > 1280)
+ {
+ setup->targetBitsInit = sub(setup->targetBitsInit, 1);
+ }
+ if (setup->total_bits > 2560)
+ {
+ setup->targetBitsInit = sub(setup->targetBitsInit, 1);
+ }
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ setup->targetBitsInit -= 1;
+ }
+# endif
+
+ setup->targetBitsAri = setup->total_bits;
+
+ SWITCH (encoder->frame_dms)
+ {
+ case 25:
+ /* 9830 = 2.4 * 2^12 */
+ setup->ltpf_enable =
+ sub(extract_l(L_shr(L_mult0(9830, setup->total_bits), 12)), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0;
+ setup->enable_lpc_weighting = 0;
+ BREAK;
+ case 50:
+ setup->ltpf_enable = sub(sub(DEPR_i_mult(setup->total_bits, 2), 160), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0;
+ setup->enable_lpc_weighting = setup->total_bits < 240;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ setup->ltpf_enable = sub(L_shr(L_mult0(10923, setup->total_bits), 13), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0;
+ setup->enable_lpc_weighting = setup->total_bits < 360;
+ BREAK;
+# endif
+ case 100:
+ setup->enable_lpc_weighting = setup->total_bits < 480;
+ setup->ltpf_enable = sub(setup->total_bits, add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0;
+ BREAK;
+ }
+
+ setup->quantizedGainOff =
+ -(s_min(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1));
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode && encoder->fs_idx == 5)
+ {
+ setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181);
+ }
+# endif
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->frame_dms == 100 &&
+ ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) ||
+ (encoder->fs_in == 32000 && setup->targetBytes >= 81))
+ && setup->targetBytes < 340
+ && (encoder->hrmode == 0))
+# else
+ if (encoder->frame_dms == 100 &&
+ ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) ||
+ (encoder->fs_in == 32000 && setup->targetBytes >= 81))
+ && setup->targetBytes < 340
+ )
+# endif
+ {
+ setup->attack_handling = 1;
+ }
+ else if (encoder->frame_dms == 75 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) ||
+ (encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150
+# ifdef ENABLE_HR_MODE
+ && encoder->hrmode == 0
+# endif
+ )
+ {
+ setup->attack_handling = 1;
+ }
+ else
+ {
+ /* reset attack detector for bitrate switching */
+ setup->attack_handling = 0;
+ setup->attdec_filter_mem[0] = 0;
+ setup->attdec_filter_mem[1] = 0;
+ setup->attdec_detected = 0;
+ setup->attdec_position = 0;
+ setup->attdec_acc_energy = 0;
+ setup->attdec_scaling = 0;
+ }
+
+# ifdef ENABLE_HR_MODE
+ if (encoder->hrmode)
+ {
+ setup->ltpf_enable = 0;
+ }
+# endif
+ encoder->sns_damping = SNS_DAMPING;
+
+# ifdef ENABLE_HR_MODE
+ IF (encoder->hrmode)
+ {
+ encoder->sns_damping = SNS_DAMPING_HRMODE;
+ IF (encoder->fs_idx >= 4)
+ {
+ IF ((encoder->frame_dms == 100) & (setup->total_bits > 4400))
+ {
+ encoder->sns_damping = SNS_DAMPING_HRMODE_UB_10MS;
+ }
+#ifdef CR8_G_ADD_75MS
+ IF ((encoder->frame_dms == 75) & (setup->total_bits > 3300))
+ {
+ encoder->sns_damping = SNS_DAMPING_HRMODE_UB_7_5MS;
+ }
+#endif
+ IF ((encoder->frame_dms == 50) & (setup->total_bits > 2300))
+ {
+ encoder->sns_damping = SNS_DAMPING_HRMODE_UB_5MS;
+ }
+ IF ((encoder->frame_dms == 25) & (setup->total_bits > 1150))
+ {
+ encoder->sns_damping = SNS_DAMPING_HRMODE_UB_2_5MS;
+ }
+ }
+ }
+
+ if (encoder->hrmode && encoder->fs_idx >= 4)
+ {
+ int real_rate = setup->targetBytes * 8 * 10000 / encoder->frame_dms;
+ setup->regBits = real_rate / 12500;
+
+ if (encoder->fs_idx == 5)
+ {
+ if (encoder->frame_dms == 100)
+ {
+ setup->regBits += 2;
+ }
+#ifdef CR8_G_ADD_75MS
+ if (encoder->frame_dms == 75)
+ {
+ setup->regBits +=1;
+ }
+#endif
+ if (encoder->frame_dms == 25)
+ {
+ setup->regBits -= 6;
+ }
+ }
+ else
+ {
+ if (encoder->frame_dms == 25)
+ {
+ setup->regBits -= 6;
+ }
+ else if (encoder->frame_dms == 50)
+ {
+ setup->regBits += 0;
+ }
+#ifdef CR8_G_ADD_75MS
+ if (encoder->frame_dms == 75)
+ {
+ setup->regBits +=2;
+ }
+#endif
+ if (encoder->frame_dms == 100)
+ {
+ setup->regBits += 5;
+ }
+ }
+
+
+ if (setup->regBits < 6)
+ {
+ setup->regBits = 6;
+ }
+ if (setup->regBits > 23)
+ {
+ setup->regBits = 23;
+ }
+ }
+ else
+ {
+ setup->regBits = -1;
+ }
+# endif
+ }
+
+ encoder->bitrate = bitrate;
+
+ return LC3PLUS_OK;
+}
+
diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e89829daa335c1f4925d447fcea73df6752a1cb
--- /dev/null
+++ b/lib_lc3plus/setup_enc_lc3.h
@@ -0,0 +1,131 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef SETUP_ENC_LC3_H
+#define SETUP_ENC_LC3_H
+
+#include "constants.h"
+
+/* Channel state and bitrate-derived values go in this struct */
+typedef struct
+{
+#ifdef ENABLE_HR_MODE
+ Word32 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */
+#else
+ Word16 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */
+#endif
+ Word32 *mdct_mem32; /* MDCT_MEM_LEN_MAX */
+ Word32 targetBitsOff;
+ Word16 targetBytes;
+ Word16 total_bits;
+ Word16 targetBitsInit;
+ Word16 targetBitsAri;
+ Word16 enable_lpc_weighting;
+ Word16 ltpf_enable;
+ Word16 quantizedGainOff;
+ Word16 tns_bits;
+ Word16 targetBitsQuant;
+ Word16 olpa_mem_s6k4_exp;
+ Word16 olpa_mem_pitch;
+#ifdef CR9_F_PITCH_WIN_LEN_FIX
+ Word16 pitch_flag;
+#endif
+ Word16 ltpf_mem_in_exp;
+ Word16 ltpf_mem_normcorr;
+ Word16 ltpf_mem_mem_normcorr;
+ Word16 ltpf_mem_ltpf_on;
+ Word16 ltpf_mem_pitch;
+ Word16 mem_targetBits;
+ Word16 mem_specBits;
+ Word16 x_exp;
+ Word16 resamp_exp;
+ Word16 attack_handling; /* flag to enable attack handling */
+ Word16 attdec_filter_mem[2];
+ Word16 attdec_detected;
+ Word16 attdec_position;
+ Word32 attdec_acc_energy;
+ Word16 attdec_scaling;
+#ifdef ENABLE_HR_MODE
+ Word16 regBits;
+ Word32 resamp_mem32[120] ALIGN_BUFFER_STRUCT;
+#else
+ Word32 resamp_mem32[60] ALIGN_BUFFER_STRUCT;
+#endif
+#ifdef ENABLE_HR_MODE
+ Word16 r12k8_mem_in[120] ALIGN_BUFFER_STRUCT;
+#else
+ Word16 r12k8_mem_in[60] ALIGN_BUFFER_STRUCT;
+#endif
+ Word32 r12k8_mem_50[2] ALIGN_BUFFER_STRUCT;
+#ifdef CR8_G_ADD_75MS
+ Word16 r12k8_mem_out[44] ALIGN_BUFFER_STRUCT;
+#else
+ Word16 r12k8_mem_out[24] ALIGN_BUFFER_STRUCT;
+#endif
+ Word16 olpa_mem_s12k8[3] ALIGN_BUFFER_STRUCT;
+ Word16 olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16] ALIGN_BUFFER_STRUCT;
+ Word16 ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1] ALIGN_BUFFER_STRUCT;
+ Word16 n_pccw;
+ Word16 n_pc;
+
+ Word16 lfe;
+} EncSetup;
+
+/* Constants and sampling rate derived values go in this struct */
+struct LC3PLUS_Enc
+{
+ EncSetup *channel_setup[MAX_CHANNELS];
+#ifdef ENABLE_HR_MODE
+ const Word32 *W_fx;
+#else
+ const Word16 *W_fx;
+#endif
+ const Word16 *bands_offset;
+
+ Word32 fs; /* encoder sampling rate 44.1 -> 48 */
+ Word32 fs_in; /* input sampling rate */
+ Word32 bitrate; /* global bitrate */
+ Word16 fs_idx; /* sampling rate index */
+ Word16 frame_length; /* audio samples / frame */
+ Word16 channels; /* number of channels */
+ Word16 epmode; /* error protection mode */
+ Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/
+ Word8 lc3_br_set; /* indicate if bitrate has been set */
+
+ Word16 yLen;
+ Word16 W_size;
+ Word16 la_zeroes;
+ Word16 stEnc_mdct_mem_len;
+ Word16 bands_number;
+ Word16 nSubdivisions;
+ Word16 ltpf_mem_in_len;
+ Word16 envelope_bits;
+ Word16 global_gain_bits;
+ Word16 noise_fac_bits;
+ Word16 BW_cutoff_bits;
+ Word16 r12k8_mem_in_len;
+ Word16 r12k8_mem_out_len;
+ Word16 near_nyquist_index;
+ Word16 near_nyquist_flag;
+
+ Word16 epmr;
+ Word16 combined_channel_coding;
+ Word32 bandwidth;
+ Word32 bandwidth_preset;
+ Word32 bw_ctrl_active;
+ Word16 bw_ctrl_cutoff_bin;
+ Word16 bw_index;
+ Word16 attdec_nblocks;
+ Word16 attdec_damping;
+ Word16 attdec_hangover_thresh;
+ Word16 hrmode;
+ Word16 sns_damping;
+};
+
+#endif
diff --git a/lib_lc3plus/sns_compute_scf_fx.c b/lib_lc3plus/sns_compute_scf_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..d56a1a7f855636c31302a8d8a2da99461db9bf3f
--- /dev/null
+++ b/lib_lc3plus/sns_compute_scf_fx.c
@@ -0,0 +1,166 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf,
+ Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping
+ )
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 i, s, s2, nf, tmp;
+ Word32 L_mean, L_tmp;
+ Word32 *d3_fx;
+ Word16 *d3_fx_exp;
+ Word16 *d4_fx;
+ Word16 *scf_smooth;
+ );
+
+ UNUSED(attdec_damping_factor);
+
+ d3_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */
+ d3_fx_exp = scratchAlign(d3_fx, sizeof(*d3_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+ d4_fx = scratchAlign(d3_fx_exp, sizeof(*d3_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128bytes */
+ scf_smooth = scratchAlign(d4_fx, sizeof(*d4_fx) * MAX_BANDS_NUMBER); /* Size = 2 * 16 */
+
+/* Smoothing and Pre-emphasis */
+ IF (sub(n_bands, 32) < 0)
+ {
+ L_tmp = sub(32, n_bands);
+ FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
+ {
+ d2_fx[(i + L_tmp) * 2 + 1] = d2_fx[i]; move32();
+ d2_fx[(i + L_tmp) * 2 + 0] = d2_fx[i]; move32();
+ }
+ FOR (i = sub(L_tmp, 1); i >= 0; i--)
+ {
+ d2_fx[i * 4 + 3] = d2_fx[i]; move32();
+ d2_fx[i * 4 + 2] = d2_fx[i]; move32();
+ d2_fx[i * 4 + 1] = d2_fx[i]; move32();
+ d2_fx[i * 4 + 0] = d2_fx[i]; move32();
+ }
+ n_bands = 64; move16();
+ }
+ ELSE
+ IF (sub(n_bands, 64) < 0)
+ {
+ L_tmp = sub(64, n_bands);
+ FOR (i = sub(n_bands, 1); i >= L_tmp; i--)
+ {
+ d2_fx[i + L_tmp] = d2_fx[i]; move32();
+ }
+ FOR (i = sub(L_tmp, 1); i >= 0; i--)
+ {
+ d2_fx[i * 2 + 1] = d2_fx[i]; move32();
+ d2_fx[i * 2 + 0] = d2_fx[i]; move32();
+ }
+ n_bands = 64; move16();
+ }
+
+ L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[0], 24576), L_shr_pos(d2_fx[1], 2));
+ d3_fx[0] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][0]); move32();
+ d3_fx_exp[0] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][0]); move16();
+ FOR (i = 1; i < n_bands - 1; i++)
+ {
+ L_tmp = L_add(L_shr_pos(d2_fx[i], 1), L_add(L_shr_pos(d2_fx[i - 1], 2), L_shr_pos(d2_fx[i + 1], 2)));
+ d3_fx[i] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][i]); move32();
+ d3_fx_exp[i] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][i]); move16();
+ }
+ L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[n_bands - 1], 24576), L_shr_pos(d2_fx[n_bands - 2], 2));
+ d3_fx[n_bands - 1] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][n_bands - 1]); move32();
+ d3_fx_exp[n_bands - 1] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][n_bands - 1]); move16();
+
+ /* Mean */
+ s = d3_fx_exp[MAX_BANDS_NUMBER - 1];
+ s2 = add(s, 6);
+
+ L_mean = L_shr(d3_fx[0], sub(s2, d3_fx_exp[0]));
+ FOR (i = 1; i < MAX_BANDS_NUMBER; i++)
+ {
+ L_mean = L_add(L_mean, L_shr(d3_fx[i], sub(s2, d3_fx_exp[i])));
+ }
+
+ /* Noise floor at -40dB */
+ nf = BASOP_Util_Log2_16(L_mean, s);
+ nf = sub(s_max(nf, -25965), 6803);
+
+/* Log-domain */
+ FOR (i = 0; i < MAX_BANDS_NUMBER; i++)
+ {
+ d4_fx[i] = s_max(nf, BASOP_Util_Log2_16(d3_fx[i], d3_fx_exp[i])); move16();
+ }
+
+ /* Downsampling */
+ L_tmp = L_mult(d4_fx[0], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[1], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[2], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[3], 5461);
+ d3_fx[0] = L_mac(L_tmp, d4_fx[4], 2731); move32();
+ FOR (i = 1; i < M - 1; i++)
+ {
+ L_tmp = L_mult(d4_fx[i * 4 - 1], 2731);
+ L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 0], 5461);
+ L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 1], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 2], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 3], 5461);
+ d3_fx[i] = L_mac(L_tmp, d4_fx[i * 4 + 4], 2731); move32();
+ }
+ L_tmp = L_mult(d4_fx[59], 2731);
+ L_tmp = L_mac(L_tmp, d4_fx[60], 5461);
+ L_tmp = L_mac(L_tmp, d4_fx[61], 8192);
+ L_tmp = L_mac(L_tmp, d4_fx[62], 8192);
+ d3_fx[M - 1] = L_mac(L_tmp, d4_fx[63], 8192); move32();
+
+/* Remove mean and scaling */
+ L_mean = L_shr_pos(d3_fx[0], 4);
+ FOR (i = 1; i < M; i++)
+ {
+ L_mean = L_add(L_mean, L_shr_pos(d3_fx[i], 4));
+ }
+
+ FOR (i = 0; i < M; i++)
+ {
+ scf[i] = mult_r(sns_damping, round_fx(L_shl_pos(L_sub(d3_fx[i], L_mean), 1)));
+ move16();
+ }
+
+ /* scale factor smoothing */
+ IF (scf_smoothing_enabled)
+ {
+ scf_smooth[0] = L_shr(L_mult0(L_add(L_add(scf[0], scf[1]), scf[2]), 10923), 15);
+ L_mean = scf_smooth[0]; move16();
+ scf_smooth[1] = L_shr(L_add(L_add(L_add(scf[0], scf[1]), scf[2]), scf[3]), 2);
+ L_mean = L_add(L_mean, scf_smooth[1]);
+ FOR (i = 2; i < M - 2; i++)
+ {
+ L_tmp = L_add(L_add(L_add(L_add(scf[i - 2], scf[i - 1]), scf[i]), scf[i + 1]), scf[i + 2]);
+ tmp = norm_s(L_shr(L_abs(L_tmp), 15));
+ if (tmp > 0) {
+ tmp = sub(16, tmp);
+ L_tmp = L_shr(L_tmp, tmp);
+ }
+ scf_smooth[i] = L_shr(L_mult0(L_tmp, 13107), sub(16, tmp));
+ L_mean = L_add(L_mean, scf_smooth[i]);
+ }
+ scf_smooth[M - 2] = L_shr(L_add(L_add(L_add(scf[M - 4], scf[M - 3]), scf[M - 2]), scf[M - 1]), 2);
+ L_mean = L_add(L_mean, scf_smooth[M - 2]);
+ scf_smooth[M - 1] = L_shr(L_mult0(L_add(L_add(scf[M - 3], scf[M - 2]), scf[M - 1]), 10923), 15);
+ L_mean = L_add(L_mean, scf_smooth[M - 1]);
+
+ L_mean = L_shr(L_mean, 4);
+
+ FOR (i = 0; i < M; i++)
+ {
+ scf[i] = mult_r(attdec_damping_factor, sub(scf_smooth[i], L_mean));
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/sns_interpolate_scf_fx.c b/lib_lc3plus/sns_interpolate_scf_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..e71825d075dc6e04e0139ca0b554ddd8c556f13b
--- /dev/null
+++ b/lib_lc3plus/sns_interpolate_scf_fx.c
@@ -0,0 +1,154 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+void processSnsInterpolateScf_fx(
+#ifdef ENABLE_HR_MODE
+ Word32 *scf_q, Word32 mdct_scf[],
+#else
+ Word16 *scf_q, Word16 mdct_scf[],
+#endif
+ Word16 mdct_scf_exp[], Word16 inv_scf,
+ Word16 n_bands, Word8 *scratchBuffer)
+{
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(
+ Word32 i, tmp2;
+ Word32 *scf_int;
+ Word32 tmp;
+ Word32 *scf_tmp;
+ );
+#else
+ Dyn_Mem_Deluxe_In(
+ Word16 i, tmp2;
+ Word16 *scf_int;
+ Word16 tmp;
+ Word16 *scf_tmp;
+ );
+#endif
+
+#ifdef ENABLE_HR_MODE
+ scf_int = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+ scf_tmp = (Word32 *)scratchAlign(scf_int, 4 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */
+#else
+ scf_int = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */
+ scf_tmp = (Word16 *)scratchAlign(scf_int, 2 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */
+#endif
+
+ /* Interpolation */
+ scf_int[0] = scf_q[0];
+ scf_int[1] = scf_q[0];
+ FOR (i = 1; i < M; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ tmp = L_sub(scf_q[i], scf_q[i - 1]);
+ tmp2 = L_shr(tmp, 2);
+ tmp = L_shr(tmp, 3);
+ scf_int[i * 4 - 2] = L_add(scf_q[i - 1], tmp);
+ scf_int[i * 4 - 1] = L_add(scf_int[i * 4 - 2], tmp2);
+ scf_int[i * 4] = L_add(scf_int[i * 4 - 1], tmp2);
+ scf_int[i * 4 + 1] = L_add(scf_int[i * 4], tmp2);
+#else
+ tmp = sub(scf_q[i], scf_q[i - 1]);
+ tmp2 = mult_r(tmp, 8192);
+ tmp = mult_r(tmp, 4096);
+ scf_int[i * 4 - 2] = add(scf_q[i - 1], tmp);
+ scf_int[i * 4 - 1] = add(scf_int[i * 4 - 2], tmp2);
+ scf_int[i * 4] = add(scf_int[i * 4 - 1], tmp2);
+ scf_int[i * 4 + 1] = add(scf_int[i * 4], tmp2);
+#endif
+ }
+#ifdef ENABLE_HR_MODE
+ scf_int[62] = L_add(scf_int[61], tmp2);
+ scf_int[63] = L_add(scf_int[62], tmp2);
+#else
+ scf_int[62] = add(scf_int[61], tmp2);
+ scf_int[63] = add(scf_int[62], tmp2);
+#endif
+
+ /* 8 kHz mode for 2.5 ms */
+ IF (sub(n_bands, 32) < 0)
+ {
+#ifdef ENABLE_HR_MODE
+ basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word32));
+#else
+ basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word16));
+#endif
+ tmp = sub(32, n_bands);
+ FOR (i = 0; i < tmp; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ scf_int[i] = L_add(L_shr(L_add(scf_tmp[4 * i], scf_tmp[4 * i + 1]), 2),
+ L_shr(L_add(scf_tmp[4 * i + 2], scf_tmp[4 * i + 3]), 2));
+#else
+ /* 8192 = 0.25 * 2^15 */
+ scf_int[i] = add(mac_r(L_mult(scf_tmp[4 * i], 8192), scf_tmp[4 * i + 1], 8192),
+ mac_r(L_mult(scf_tmp[4 * i + 2], 8192), scf_tmp[4 * i + 3], 8192));
+#endif
+ }
+
+ FOR (i = 0; i < n_bands - tmp; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ scf_int[tmp + i] = L_shr(L_add(scf_tmp[4 * tmp + 2 * i], scf_tmp[4 * tmp + 2 * i + 1]), 1);
+#else
+ scf_int[tmp + i] = mac_r(L_mult(scf_tmp[4 * tmp + 2 * i], 16384), scf_tmp[4 * tmp + 2 * i + 1], 16384);
+#endif
+ }
+ }
+ ELSE
+ /* For 5ms */
+ IF (sub(n_bands, 64) < 0)
+ {
+ tmp = sub(64, n_bands);
+ FOR (i = 0; i < tmp; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ scf_int[i] = L_shr(L_add(scf_int[2 * i], scf_int[2 * i + 1]), 1);
+#else
+ scf_int[i] = mac_r(L_mult(scf_int[2 * i], 16384), scf_int[2 * i + 1], 16384);
+#endif
+ }
+ FOR (; i < n_bands; i++)
+ {
+ scf_int[i] = scf_int[tmp + i]; move16();
+ }
+#ifdef ENABLE_HR_MODE
+ move16(); // 32 bit operations have twice the complexity weight of 16 bit operations
+#endif
+ }
+
+ /* Inversion at encoder-side*/
+ IF (inv_scf == 1)
+ {
+ FOR (i = 0; i < n_bands; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ scf_int[i] = L_negate(scf_int[i]);
+#else
+ scf_int[i] = negate(scf_int[i]);
+#endif
+ }
+ }
+
+/* Linear Domain */
+ FOR (i = 0; i < n_bands; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ /* scf_int is in Q26, BASOP_Util_InvLog2_pos requires Q25 data */
+ mdct_scf[i] = BASOP_Util_InvLog2_pos(L_shr(scf_int[i], 1), &mdct_scf_exp[i]);
+#else
+ mdct_scf[i] = BASOP_Util_InvLog2_16(scf_int[i], &mdct_scf_exp[i]);
+#endif
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
diff --git a/lib_lc3plus/sns_quantize_scf_fx.c b/lib_lc3plus/sns_quantize_scf_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..991381285463e0b583ec8edcd3aeccdfb8cfc2af
--- /dev/null
+++ b/lib_lc3plus/sns_quantize_scf_fx.c
@@ -0,0 +1,834 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static Word16 stage1_base( /* o : idx */
+ const Word16 *t, /* i : target SCFs */
+#ifdef ENABLE_HR_MODE
+ const Word32 *cdbk, /* i : SCFs cdbk */
+#else
+ const Word16 *cdbk, /* i : SCFs cdbk */
+#endif
+ const Word16 R /* i : number of rows in codebook */
+)
+{
+ Counter row;
+ Word16 k_ptr, idx;
+ Word32 L_min_mse, L_mse;
+ Counter col;
+#ifdef ENABLE_HR_MODE
+ Word32 err;
+#else
+ Word16 err;
+#endif
+
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("stage1_base", sizeof(struct {
+ Counter row, col;
+ Word16 k_ptr, idx, err;
+ Word32 L_min_mse, L_mse;
+ }));
+#endif
+#ifdef WMOPS
+ BASOP_sub_sub_start("stage1_base");
+#endif
+
+/* find first vector error energy for */
+/* loop probably works with saturation , but it should not occur anyway */
+ L_min_mse = L_add(0, 0); /* init acc with absolute min mse sofar */
+ FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */
+ {
+#ifdef ENABLE_HR_MODE
+ err = L_sub(cdbk[col], L_deposit_h(t[col])); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max
+ target is approx similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */
+ L_min_mse = L_add(L_min_mse, Mpy_32_32_lc3plus(err, err));
+#else
+ err = sub(cdbk[col], t[col]); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max target is approx
+ similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */
+ L_min_mse = L_mac0(L_min_mse, err, err); /* max L_min_mse is 8*4096*4096 =2.^(3+12+12) = 2.^27 */
+#endif
+ }
+
+ idx = 0; move16();
+
+ k_ptr = M / 2; move16(); /* ptr init to second row */
+ FOR (row = 1; row < R; row++)
+ {
+ /* loop probably works with saturation , but it should not occur anyway */
+
+ L_mse = L_add(L_min_mse, 0); /* init acc with min mse sofar , */
+ FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */
+ {
+#ifdef ENABLE_HR_MODE
+ err = L_sub(cdbk[k_ptr++], L_deposit_h(t[col]));
+ L_mse = L_sub(L_mse, Mpy_32_32_lc3plus(err, err));
+#else
+ err = sub(cdbk[k_ptr++], t[col]);
+ L_mse = L_msu0(L_mse, err,
+ err); /* NB subtraction from best MSE error sofar in acc , saturation may not occur */
+#endif
+ }
+
+ L_min_mse = L_sub(L_min_mse, L_max(L_mse, 0L)); /* ALWAYS update best MSE error sofar */
+
+ if (L_mse > 0L) /* if acc value still is positive a new lower error energy vector was found in this row */
+ {
+ idx = row; move16(); /* update 1-8 bits idx */
+ }
+
+ /* this inner loop(always updating L_min_mse), (L_msu, if ) consumes AV 19, WC ~20 STL cycles ,
+ compared to a conventional(L_mac, IF( ) ) AV 21 WC ~23 STL cycles per
+ loop */
+ }
+ ASSERT(idx >= 0 && idx < R);
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+
+ return idx;
+}
+
+static void first_stage_split_search(
+#ifdef ENABLE_HR_MODE
+ const Word32 *cbk_LF, const Word32 *cbk_HF,
+#else
+ const Word16 *cbk_LF, const Word16 *cbk_HF,
+#endif
+ const Word16 *target,
+ const Word16 nbCbkEntries, Word16 *idxLF, Word16 *idxHF)
+{
+ /* find base index for each SCF split */
+ *idxLF = stage1_base(target, cbk_LF, nbCbkEntries);
+ *idxHF = stage1_base((&target[M / 2]), cbk_HF, nbCbkEntries);
+}
+
+static void processDeQuantize_stage1ScfDecStage1_fx(
+#ifdef ENABLE_HR_MODE
+ const Word32 *cbk_LF, const Word32 *cbk_HF,
+#else
+ const Word16 *cbk_LF, const Word16 *cbk_HF,
+#endif
+ Word16 st1_idx0, Word16 st1_idx1,
+#ifdef ENABLE_HR_MODE
+ Word32 *st1_vector
+#else
+ Word16 *st1_vector
+#endif
+ )
+{
+ Counter col;
+ Word16 offset0, offset1;
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_In("processDeQuantize_stage1ScfDecStage1_fx", sizeof(struct {
+ Word16 offset0, offset1;
+ Counter col;
+ }));
+#endif
+
+ offset0 = shl_pos(st1_idx0, 3); /* mult by M/2 */
+ offset1 = shl_pos(st1_idx1, 3);
+ FOR (col = 0; col < M / 2; col++)
+ {
+ st1_vector[col] = cbk_LF[offset0++]; move16();
+ st1_vector[col + 8] = cbk_HF[offset1++]; move16();
+#ifdef ENABLE_HR_MODE
+ move16();
+ move16();
+#endif
+ }
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+}
+
+void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len)
+{
+ Word32 i;
+ FOR (i = 0; i < len; i++)
+ {
+ w16_arr[i] = extract_l(L_shr_pos(w32_arr[i], shft_val));
+ move16();
+ }
+ return;
+}
+
+void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr,Word32 len)
+{
+ Word32 i;
+ FOR (i = 0; i < len; i++)
+ {
+ w16_arr[i] = round_fx(w32_arr[i]);
+ move16();
+ }
+ return;
+}
+
+static void processQuantize_stage1ScfEncStage1_fx(const Word16 *target_st1,
+#ifdef ENABLE_HR_MODE
+ Word32 *st1_vector,
+#else
+ Word16 *st1_vector,
+#endif
+ Word16 *st1_idx0Ptr, Word16 *st1_idx1Ptr)
+
+{
+#ifdef WMOPS
+ BASOP_sub_sub_start("processQuantize_stage1ScfEncStage1_fx");
+#endif
+
+#ifdef ENABLE_HR_MODE
+ first_stage_split_search(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, target_st1, SCF_STAGE1_NBCDKENTRIES,
+ st1_idx0Ptr, st1_idx1Ptr);
+
+ processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, *st1_idx0Ptr,
+ *st1_idx1Ptr, st1_vector);
+#else
+ first_stage_split_search(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, target_st1, SCF_STAGE1_NBCDKENTRIES,
+ st1_idx0Ptr, st1_idx1Ptr);
+
+ processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, *st1_idx0Ptr,
+ *st1_idx1Ptr, st1_vector);
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+
+ return;
+}
+
+/* gain-shape MSE search in warped SCF-residual domain, synthesis in SCF resiudal domain allows for easy weighting */
+
+static void pvq_enc_find_best_submode_pre_post_fx(
+#ifdef ENABLE_HR_MODE
+ const Word32 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */
+#else
+ const Word16 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */
+#endif
+ const Word16 *enc_pulses_far, Word16 *enc_pulses_near, const Word16 *enc_pulsesA, const Word16 *enc_pulsesB,
+ Word16 *sub_mode_ptr, Word16 *i_gain_ptr,
+#ifdef ENABLE_HR_MODE
+ Word32 *enc_adj_glob_warped_vec,
+#else
+ Word16 *enc_adj_glob_warped_vec,
+#endif
+ Word8 *scratchBuffer) /* Size = 18 * M */
+{
+
+ Counter L_section, idx;
+#ifdef ENABLE_HR_MODE
+ const Word32 *search_en1shape[N_SCF_SHAPES_ST2];
+#else
+ const Word16 *search_en1shape[N_SCF_SHAPES_ST2];
+#endif
+ const Word16 *search_gainTab[N_SCF_SHAPES_ST2];
+ Word16 search_n_gains[N_SCF_SHAPES_ST2];
+ Word32 L_mse, L_mse_min, L_idx;
+ Word16 * pulses_far, *pulses_near, *pulsesAB, *pulsesA;
+#ifdef ENABLE_HR_MODE
+ Word32 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA;
+#else
+ Word16 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA;
+#endif
+#ifdef ENABLE_HR_MODE
+ Word32 tmp, err;
+#else
+ Word16 tmp, err;
+#endif
+ Counter i;
+
+#ifdef DYNMEM_COUNT
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct {
+ Counter i, L_section, idx;
+ Word32 *search_en1shape[N_SCF_SHAPES_ST2];
+ Word16 *search_gainTab[N_SCF_SHAPES_ST2];
+ Word16 search_n_gains[N_SCF_SHAPES_ST2];
+ Word32 L_mse, L_mse_min, L_idx;
+ Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA;
+ Word32 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA;
+ Word32 tmp, err;
+ }));
+#else
+ Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct {
+ Counter i, L_section, idx;
+ Word16 *search_en1shape[N_SCF_SHAPES_ST2];
+ Word16 *search_gainTab[N_SCF_SHAPES_ST2];
+ Word16 search_n_gains[N_SCF_SHAPES_ST2];
+ Word32 L_mse, L_mse_min, L_idx;
+ Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA;
+ Word16 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA;
+ Word16 tmp, err;
+ }));
+#endif /* ENABLE_HR_MODE */
+#endif /* DYNMEM_COUNT */
+
+ pulses_near = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */
+
+ pulsesAB = (Word16 *)scratchAlign(pulses_near, sizeof(*pulses_near) * M); /* Size = 2 * M */
+
+ pulsesA = (Word16 *)scratchAlign(pulsesAB, sizeof(*pulsesAB) * M); /* Size = 2 * M */
+
+#ifdef ENABLE_HR_MODE
+ target_w = (Word32 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */
+
+ shape_near = (Word32 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 4 * M */
+
+ shapeAB = (Word32 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 4 * M */
+
+ shapeA = (Word32 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 4 * M */
+#else
+ target_w = (Word16 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */
+
+ shape_near = (Word16 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 2 * M */
+
+ shapeAB = (Word16 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 2 * M */
+
+ shapeA = (Word16 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 2 * M */
+#endif
+
+ pulses_far = (Word16 *)scratchAlign(shapeA, sizeof(*shapeA) * M); /* Size = 2 * M */
+
+#ifdef ENABLE_HR_MODE
+ shape_far = (Word32 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */
+#else
+ shape_far = (Word16 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("pvq_enc_find_best_submode_pre_post_fx");
+#endif
+
+ /* construct pulse vectors and en1 normalized shape vectors */ /* use shape Q in Q14 */
+ basop_memmove(pulses_far, enc_pulses_far, M * sizeof(*pulses_far));
+ basop_memmove(pulses_near, enc_pulses_near, M * sizeof(*pulses_near));
+ basop_memmove(target_w, target_st2, M * sizeof(*target_w));
+
+ pvq_dec_en1_normQ14_fx(shape_near, pulses_near, sns_Kval[2][0], M); /* near outlier mode */
+ pvq_dec_en1_normQ14_fx(shape_far, pulses_far, sns_Kval[3][0], M); /* far outlier mode */
+
+ /* regular mode(with a split), prepare vectors of full length M */
+ basop_memmove(pulsesAB, enc_pulsesA, N_SETA * sizeof(*pulsesAB));
+ basop_memmove(pulsesA, enc_pulsesA, N_SETA * sizeof(*pulsesA));
+
+ FOR (i = N_SETA; i < M; i++)
+ {
+ pulsesAB[i] = enc_pulsesB[sub(i, N_SETA)]; move16();
+ }
+
+ IF (M > N_SETA)
+ {
+ basop_memset(&pulsesA[N_SETA], 0, (M - N_SETA) * sizeof(*pulsesA));
+ }
+
+ pvq_dec_en1_normQ14_fx(shapeAB, pulsesAB, sns_Kval[0][0], M);
+ /* regular AB , b_pulses = 1 ;*/ /* OPT: combine with shapeA */
+
+ pvq_dec_en1_normQ14_fx(shapeA, pulsesA, sns_Kval[1][0], M);
+ /* regular A , b_pulses = 0 */ /* OPT: M-> N_SETA */
+
+ /* setup search structure */
+
+ /* now aligned with order of j {regular=0, regular_lf=1, outlier_near=2, outlier far=3} */
+
+ search_en1shape[0] = shapeAB;
+ search_gainTab[0] = sns_gaintabPtr[0];
+ search_n_gains[0] = sns_gainSz[0]; /* assumes whole bits */
+
+ search_en1shape[1] = shapeA;
+ search_gainTab[1] = sns_gaintabPtr[1];
+ search_n_gains[1] = sns_gainSz[1]; /* assumes whole bits */
+
+ search_en1shape[2] = shape_near;
+ search_gainTab[2] = sns_gaintabPtr[2];
+ search_n_gains[2] = sns_gainSz[2]; /*assume whole bits */
+
+ search_en1shape[3] = shape_far;
+ search_gainTab[3] = sns_gaintabPtr[3];
+ search_n_gains[3] = sns_gainSz[3]; /*assume whole bits */
+
+ /* start actual search loop */
+
+ /* basic raw MSE loop, */
+ L_mse_min = INT32_MAX; move32();
+ L_idx = L_deposit_l(-1); /* section in low 2 bits* gain idx above */
+
+ FOR (L_section = 0; L_section < N_SCF_SHAPES_ST2; L_section++)
+ {
+ /* raw MSE over gain and shape */
+ FOR (idx = 0; idx < search_n_gains[L_section]; idx++)
+ {
+ /* MSE ( proc_target_local[i]-adjGain[i]*en1Shape[i] ) */
+
+ L_mse = L_deposit_l(0);
+ FOR (i = 0; i < M; i++)
+ {
+#ifdef ENABLE_HR_MODE
+ tmp = Mpy_32_16_lc3plus(search_en1shape[L_section][i], search_gainTab[L_section][idx]); /* Q30 + 14 - 15 = Q29 */
+ err = L_sub(target_w[i], tmp); /* both in Q29 */
+ L_mse = L_add(L_mse, L_shr_pos(Mpy_32_32_lc3plus(err, err), 1)); /* Q29+29-31 = Q27 */
+#else
+ tmp = mult_r(search_gainTab[L_section][idx], search_en1shape[L_section][i]); /* Q15+14+1-16= Q14 */
+ err = sub(target_w[i], tmp); /* both in Q14 */
+ L_mse = L_mac0(L_mse, err, err); /* Q14+14 = Q28 */
+#endif /* Q14+14 = Q28 */
+ }
+
+ IF (L_sub(L_mse, L_mse_min) < 0) /* OPT: always update L_mse_min) */
+ {
+ L_mse_min = L_mse; move32();
+ L_idx = L_mac0(L_section, idx, 1 << 2); /* save both section and gain idx */
+ }
+ } /* gains */
+ } /*submodes*/
+
+ L_section = L_and(0x3L, L_idx); /* section was stored in two lowest bits */
+ ASSERT(L_section >= 0 && L_section <= 3);
+ *i_gain_ptr = extract_l(L_shr_pos(L_idx, 2)); /*1,2,3 bit gain */
+ ASSERT(*i_gain_ptr >= 0 && *i_gain_ptr <= 7);
+
+ /* returns a scaled and transformed vector, ___EXACTLY__ as a decoder would scale it */
+ ASSERT(enc_adj_glob_warped_vec != NULL);
+ {
+ /* warp/rotate search result to SCF residual domain */
+#ifdef ENABLE_HR_MODE
+ idct32_32_fx(search_en1shape[L_section], target_w);
+#else
+ idct16_fx(search_en1shape[L_section], target_w); /* fwd synthesis warping */
+#endif
+ /* actual synthesis gain scaling in SCF-residual domain, for easy weighting analysis */
+ pvq_dec_scale_vec_fx(target_w, search_gainTab[L_section][*i_gain_ptr], enc_adj_glob_warped_vec);
+ }
+
+ *sub_mode_ptr = extract_l(L_section);
+ move16(); /* 0,1,2,3 */
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return;
+}
+
+static void processQuantize_stage2ScfEncStage2_fx(
+#ifdef ENABLE_HR_MODE
+ const Word32 *target_st2, Word32 *st2_vector,
+#else
+ const Word16 *target_st2, Word16 *st2_vector,
+#endif
+ Word32 *L_prm_idx,
+ Word16 submodes, Word8 *scratchBuffer) /* Size = 26 * M + 48 */
+{ /*func */
+#ifdef ENABLE_HR_MODE
+ Word32 *proc_target;
+#else
+ Word16 *proc_target;
+#endif
+
+ Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB;
+
+ Word16 *pulses_fin, *pulses_proj;
+ Word32 L_tmp;
+
+ Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx;
+
+ PvqEntry_fx enc_PVQ_OA, enc_PVQ_B;
+ Word16 submode, i_gain, submodeMSB, submodeLSB;
+ Word32 * L_search_corr, *L_search_en;
+#ifdef ENABLE_HR_MODE
+ Word16 * proc_target_lp;
+#endif
+
+#ifdef DYNMEM_COUNT
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct {
+ Word32 *proc_target;
+ Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB;
+ Word16 *pulses_fin, *pulses_proj;
+ Word32 L_tmp;
+ Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx;
+ PvqEntry_fx enc_PVQ_OA, enc_PVQ_B;
+ Word16 submode, i_gain, submodeMSB, submodeLSB;
+ Word32 * L_search_corr, *L_search_en;
+ Word16 * proc_target_lp;
+ }));
+#else
+ Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct {
+ Word16 *proc_target;
+ Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB;
+ Word16 *pulses_fin, *pulses_proj;
+ Word32 L_tmp;
+ Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx;
+ PvqEntry_fx enc_PVQ_OA, enc_PVQ_B;
+ Word16 submode, i_gain, submodeMSB, submodeLSB;
+ Word32 * L_search_corr, *L_search_en;
+ }));
+#endif /* ENABLE_HR_MODE */
+#endif /* DYNMEM_COUNT */
+
+#ifdef ENABLE_HR_MODE
+ buffer_pvq_enc_find_best_submode_pre_post_fx = (Word8 *) scratchAlign(scratchBuffer, 0);
+ proc_target = (Word32 *) scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx, sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 28 * M);
+#else
+ buffer_pvq_enc_find_best_submode_pre_post_fx = scratchAlign(scratchBuffer, 0); /* Size = 18 * M */
+ proc_target =
+ (Word16 *)scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx,
+ sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 18 * M); /* Size = 2 * M */
+#endif
+
+ enc_pulses_near = (Word16 *)scratchAlign(proc_target, sizeof(*proc_target) * M); /* Size = 2 * M */
+ enc_pulsesA = (Word16 *)scratchAlign(enc_pulses_near, sizeof(*enc_pulses_near) * M); /* Size = 2 * N_SETA */
+ enc_pulsesB = (Word16 *)scratchAlign(enc_pulsesA, sizeof(*enc_pulsesA) * N_SETA); /* Size = 2 * N_SETB */
+ pulses_fin = (Word16 *)scratchAlign(enc_pulsesB, sizeof(*enc_pulsesB) * N_SETB); /* Size = 2 * N_SCF_SHAPES_ST2 */
+ pulses_proj =
+ (Word16 *)scratchAlign(pulses_fin, sizeof(*pulses_fin) * N_SCF_SHAPES_ST2); /* Size = 2 * N_SCF_SHAPES_ST2 */
+ L_search_corr =
+ (Word32 *)scratchAlign(pulses_proj, sizeof(*pulses_proj) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */
+ L_search_en = (Word32 *)scratchAlign(L_search_corr,
+ sizeof(*L_search_corr) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */
+ enc_pulses_far = (Word16 *)scratchAlign(L_search_en, sizeof(*L_search_en) * N_SCF_SHAPES_ST2); /* Size = 2 * M */
+
+#ifdef ENABLE_HR_MODE
+ proc_target_lp = (Word16 *)buffer_pvq_enc_find_best_submode_pre_post_fx; /* size = 2*M */
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("processQuantize_stage2ScfEncStage2_fx");
+#endif
+
+ /* fixed setup for a given bitrate of 38 , no moves needed */
+ /* k_far = sns_Kval[3][0]; */
+ /* k_near = sns_Kval[2][0]; */
+ /* kA = sns_Kval[1][0]; */ /* regular, regular_lf */
+ /* kB is always 1 */
+
+ /* NB these search indecese do not correspond exactly to specification shape_index j */
+
+ pulses_fin[0] = sns_Kval[3][0]; /* far 6 */
+ pulses_fin[1] = sns_Kval[2][0]; /* near 8 */
+ pulses_fin[2] = sns_Kval[1][0]; /* section A 10 */
+ pulses_fin[3] = sns_Kval[0][1]; /* section B 1 */
+
+ pulses_proj[0] = sns_Kval[3][0];
+ pulses_proj[1] = 0;
+ pulses_proj[2] = 0;
+ pulses_proj[3] = 0;
+
+ /* pre_process */
+#ifdef ENABLE_HR_MODE
+ dct32_fx(target_st2, proc_target); /* enc analysis */
+ downshift_w32_arr(proc_target, proc_target_lp, 16, M);
+
+ /* get the initial four integer shape candidate vectors, no normalization at this stage */
+ pvq_enc_search_fx(proc_target_lp, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr,
+ L_search_en, pulses_fin, pulses_proj, M, N_SETA);
+#else
+ Word32 target_st2_32[M]; Word32 proc_target_32[M]; int i;
+
+ FOR (i = 0; i < M; i++)
+ {
+ target_st2_32[i] = L_shl_pos(target_st2[i], 16);
+ }
+
+ dct32_fx(target_st2_32, proc_target_32); /* enc analysis */
+
+ downshift_w32_arr(proc_target_32, proc_target, 16, M);
+
+ /* get the initial four integer shape candidate vectors, no normalization at this stage */
+ pvq_enc_search_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr,
+ L_search_en, pulses_fin, pulses_proj, M, N_SETA);
+#endif
+
+ /* scale with gains a after a unit energy fwd transform */
+ /* apply transform to each candidate shape vector priot to gain-shape search loop */
+ submode = submodes; /* used as input solely to debug/unit test a specific shape mode */
+
+ /*target should be in a linearized residual domain target */
+ /* search pre, synthesis post*/
+ pvq_enc_find_best_submode_pre_post_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB,
+ &submode, &i_gain, st2_vector,
+ buffer_pvq_enc_find_best_submode_pre_post_fx); /* Q14 tr out */
+
+ /* send parameters to multiplexor as a series/vector of Long Words */
+ /* 0 : 0..3 submode */
+ /* 1 : 0..7 gain_ind */
+ /* 2 : 0..1 LeadSign ind */
+ /* 3 : 25 bit MPVQ index outl_near or A part */
+ /* 4 : 3.7 to 21 bits MPVQ index B part OR -2 */
+
+ L_prm_idx[0] = L_deposit_l(submode); /* complete submode fwd'ed to ari_codec as 0,1,2,3 */
+
+ submodeMSB = shr_pos(submode, 1); /* LSB of submode , sent as main submode bit */
+ submodeLSB = s_and(submode, 0x1); /* LSB of submode */ /* sent via shape param */
+
+ /* gain, shape indicese , incl. calls to MPVQ indexing */
+ IF (submodeMSB == 0)
+ { /* regular modes:: j=0(reg=AB) or 1(reg_lf A) */ /* regular mode, with two or one shape indices */
+
+ /* assume regular_lf part , shape_j == 1 */
+ enc_PVQ_OA =
+ mpvq_index_fx(enc_pulsesA, N_SETA, sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */
+ L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /*LS set A */
+
+ ASSERT(enc_PVQ_OA.size == (UWord32)sns_MPVQ_Sz[submode][0]);
+ L_prm_idx[3] = L_add(0L, (Word32)enc_PVQ_OA.index); /* MPVQ shape index set A fractional */
+
+ /* section B always have low indexing dynamics and is combined into one joint single index */
+ IF (submodeLSB == 0)
+ { /* regular AB , shape_j == 0*/
+ L_prm_idx[1] = L_deposit_l(i_gain); /* full established gain idx fwd'ed */ /* 2 possible values */
+ enc_PVQ_B = mpvq_index_fx(enc_pulsesB, N_SETB, 1);
+ ASSERT(((enc_PVQ_B.size << 1)) ==
+ (sns_MPVQ_Sz[submode][1])); /* two lowest indeces indicate all_zero B section */
+
+ L_tmp = L_shl_pos((Word32)enc_PVQ_B.index, 1); /* 2*section B MPVQ index */
+ L_prm_idx[4] = L_add(L_tmp, enc_PVQ_B.lead_sign_ind); move32(); /* add joint section B and LS index */
+
+ ASSERT(L_prm_idx[4] >= 0 && L_prm_idx[4] < (Word32)sns_MPVQ_Sz[submode][0]);
+ }
+ ELSE
+ {
+ L_prm_idx[1] = L_deposit_l(i_gain);
+ /* MSBs of established gain idx */ /* 2 or 4 total possible values */
+ L_prm_idx[4] = L_deposit_l(-2);
+ }
+ }
+ ELSE
+ {
+ /* outlier modes shape_j= 2(near, LSB=0) or 3(far, LSB=1) */
+
+ IF (submodeLSB == 0)
+ {
+ L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx */ /* 4 possible values */
+ enc_PVQ_OA = mpvq_index_fx(enc_pulses_near, M,
+ sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */
+ ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]);
+ L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */
+ L_prm_idx[4] = L_deposit_l(-1); /* no gain LSBs */
+ }
+ ELSE
+ {
+ L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx MSBs */ /* all 4 or 8 possible values */
+ enc_PVQ_OA = mpvq_index_fx(enc_pulses_far, M,
+ sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */
+ ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]);
+ L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */
+ L_prm_idx[4] = L_deposit_l(-2); /* */
+ }
+ L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /* LS shape single bit */
+ }
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+#ifdef DYNMEM_COUNT
+ Dyn_Mem_Out();
+#endif
+ return;
+}
+
+static Word16 scfdec_stage2_fx( /* o: ber flag */
+ const Word32 *L_prm_idx, /* set to -1 if not used */
+#ifdef ENABLE_HR_MODE
+ Word32 * st2_vector, /*o: Q14 */
+#else
+ Word16 * st2_vector, /*o: Q14 */
+#endif
+ Word8 * scratchBuffer)
+{
+ /* MPVQ deindexing, gainscaling transform and transform */
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(
+ Word16 submode;
+ Word16 submodeLSB, submodeMSB;
+ Word16 gValQ13;
+ Word16 idxB;
+ Word16 maxK;
+ Word16 BER_dec;
+ Word16 *dec_pulses;
+ Word32 *dec_en1_vec;
+ Word32 *dec_adj_glob_vec;
+ );
+#else
+ Dyn_Mem_Deluxe_In(
+ Word16 submode;
+ Word16 submodeLSB, submodeMSB;
+ Word16 gValQ13;
+ Word16 idxB;
+ Word16 maxK;
+ Word16 BER_dec;
+ Word16 *dec_pulses;
+ Word16 *dec_en1_vec;
+ Word16 *dec_adj_glob_vec;
+ );
+#endif
+
+#ifdef WMOPS
+ BASOP_sub_sub_start("scfdec_stage2_fx");
+#endif
+
+ dec_pulses = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M = 32 bytes */
+#ifdef ENABLE_HR_MODE
+ dec_en1_vec = (Word32 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */
+ dec_adj_glob_vec = (Word32 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */
+#else
+ dec_en1_vec = (Word16 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */
+ dec_adj_glob_vec = (Word16 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */
+#endif
+
+ /* get submode */
+ submode = extract_l(L_prm_idx[0]); /* 0..3 */
+
+ submodeLSB = s_and(submode, 0x1);
+ submodeMSB = shr_pos(submode, 1);
+
+ /* get initial adjustment gain vector for regular, outl_near */
+ ASSERT(L_prm_idx[1] >= 0 && L_prm_idx[1] < sns_gainSz[submode]);
+ gValQ13 = sns_gaintabPtr[submode][L_prm_idx[1]];
+ ASSERT(gValQ13 >= 0);
+
+ /* gain, shape indices, incl.calls to MPVQ deindexing */
+ IF (submodeMSB != 0)
+ {
+ /* outlier_near or outlier_far mode decoding */
+ maxK = sns_Kval[submode][0]; move16();
+ BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, M, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]);
+ }
+ ELSE
+ { /* regular mode, with potentially two shape indices */
+
+ maxK = sns_Kval[submode][0]; move16();
+ BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, N_SETA, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]);
+
+ IF (submodeLSB == 0)
+ {
+ idxB = extract_l(L_prm_idx[4]); /* 0..11 */
+ ASSERT(idxB >= 0 && idxB < (Word16)sns_MPVQ_Sz[0][1]);
+ BER_dec |= pvq_dec_deidx_fx(&(dec_pulses[N_SETA]), sns_Kval[submode][1], N_SETB, s_and(idxB, 0x1),
+ (UWord32)L_deposit_l(shr_pos(idxB, 1)));
+ /* maxK does not need to be increased as set B is not stacked */
+ }
+ ELSE
+ { /* LSB gain bit already parsed */
+ ASSERT(L_prm_idx[4] < 0);
+ basop_memset(&dec_pulses[N_SETA], 0, (N_SETB) * sizeof(*dec_pulses));
+ }
+ }
+
+ /* normalize decoded integer vector , exactly as on encoder side !! */
+ pvq_dec_en1_normQ14_fx(dec_en1_vec, dec_pulses, maxK, M);
+
+#ifdef ENABLE_HR_MODE
+ idct32_32_fx(dec_en1_vec, dec_adj_glob_vec);
+#else
+ idct16_fx(dec_en1_vec, dec_adj_glob_vec); /* fwd warping in unscaled domain */
+#endif
+
+ /* scaling aligend with encoder search */
+ pvq_dec_scale_vec_fx(dec_adj_glob_vec, gValQ13, st2_vector);
+
+#ifdef WMOPS
+ BASOP_sub_sub_end();
+#endif
+ Dyn_Mem_Deluxe_Out();
+ return BER_dec;
+}
+
+void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */
+ Word32 *L_prm_idx, /* o: indeces . negative == unused */
+#ifdef ENABLE_HR_MODE
+ Word32 *scf_q, /* o: quantized scf M */
+#else
+ Word16 *scf_q, /* o: quantized scf M */
+#endif
+ Word8 * scratchBuffer) /* Size = 28 * M + 52 */
+{
+#ifdef ENABLE_HR_MODE
+ Dyn_Mem_Deluxe_In(
+ Word32 *target_st2;
+ Word16 *st1_idx; /* stage 1 indices */
+ Word8 * buffer_processQuantize_stage2ScfEncStage2_fx;
+ Counter col;
+ );
+#else
+ Dyn_Mem_Deluxe_In(
+ Word16 *target_st2;
+ Word16 *st1_idx; /* stage 1 indices */
+ Word8 * buffer_processQuantize_stage2ScfEncStage2_fx;
+ Counter col;
+ );
+#endif
+
+#ifdef ENABLE_HR_MODE
+ target_st2 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */
+#else
+ target_st2 = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */
+#endif
+ st1_idx = (Word16 *)scratchAlign(target_st2, sizeof(*target_st2) * M); /* Size = 2 * 2 */
+ buffer_processQuantize_stage2ScfEncStage2_fx = (Word8 *)scratchAlign(st1_idx, sizeof(*st1_idx) * M);
+ /* Size = 26 * M + 48 */
+
+ /* TBD needs update */
+
+ /* 1st stage trained VQ */
+ processQuantize_stage1ScfEncStage1_fx(scf, scf_q, &st1_idx[0], &st1_idx[1]);
+ L_prm_idx[0] = L_deposit_l(st1_idx[0]);
+ L_prm_idx[1] = L_deposit_l(st1_idx[1]);
+
+/* 2nd stage PVQ-based SCF quantizer */
+ FOR (col = 0; col < M; col++)
+ {
+#ifdef ENABLE_HR_MODE
+ target_st2[col] = L_sub(L_deposit_h(scf[col]), scf_q[col]);
+#else
+ target_st2[col] = sub(scf[col], scf_q[col]);
+#endif
+ }
+
+ processQuantize_stage2ScfEncStage2_fx(target_st2, scf_q, &L_prm_idx[2], VQMODES26, /* 0xF means all submodes */
+ buffer_processQuantize_stage2ScfEncStage2_fx); /* PVQ in stage 2 */
+ Dyn_Mem_Deluxe_Out();
+}
+
+Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */
+ Word32 *L_prm_idx, /* i: indeces */
+#ifdef ENABLE_HR_MODE
+ Word32 scf_q[],
+#else
+ Word16 scf_q[],
+#endif
+ Word8 *scratchBuffer) /* o: M */
+{
+ Dyn_Mem_Deluxe_In(
+ Word16 BER_flag;
+ );
+
+ /* Decode First Stage */
+#ifdef ENABLE_HR_MODE
+ processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27,
+ extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q);
+#else
+ processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11,
+ extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q);
+#endif
+
+ /* Decode Second Stage */
+ BER_flag = scfdec_stage2_fx(&(L_prm_idx[2]), scf_q, scratchBuffer);
+
+ Dyn_Mem_Deluxe_Out();
+ return BER_flag;
+}
+
diff --git a/lib_lc3plus/tinywavein_c.h b/lib_lc3plus/tinywavein_c.h
new file mode 100644
index 0000000000000000000000000000000000000000..32789e31409c8ed4c633a53e464413122ee7d825
--- /dev/null
+++ b/lib_lc3plus/tinywavein_c.h
@@ -0,0 +1,603 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef __TINYWAVEIN_C_H__
+#define __TINYWAVEIN_C_H__
+
+/*#define SUPPORT_BWF*/
+
+#include
+#include
+#include
+
+#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__arm__) || \
+ defined(__aarch64__)
+#define __TWI_LE /* _T_iny _W_ave _I_n _L_ittle _E_ndian */
+#endif
+
+#if defined(__POWERPC__)
+#define __TWI_BE /* _T_iny _W_ave _I_n _B_ig _E_ndian */
+#endif
+
+#if !defined(__TWI_LE) && !defined(__TWI_BE)
+#error unknown processor
+#endif
+
+#define __TWI_SUCCESS (0)
+#define __TWI_ERROR (-1)
+
+#ifdef SUPPORT_BWF
+typedef struct
+{
+ float loudnessVal;
+ float loudnessRange;
+ float maxTruePeakLevel;
+ float maxMomentaryLoudnes;
+ float maxShortTermLoudness;
+} WAVEIN_LOUDNESSINFO;
+#endif
+
+typedef struct __tinyWaveInHandle
+{
+ FILE * theFile;
+ fpos_t dataChunkPos;
+ unsigned int position;
+ unsigned int length;
+ unsigned int bps;
+#ifdef SUPPORT_BWF
+ WAVEIN_LOUDNESSINFO *loudnessInfo;
+#endif
+} __tinyWaveInHandle, WAVEFILEIN;
+
+typedef struct
+{
+ short compressionCode;
+ short numberOfChannels;
+ unsigned int sampleRate;
+ unsigned int averageBytesPerSecond;
+ short blockAlign;
+ short bitsPerSample;
+ /* short extraFormatBytes ; */
+} SWavInfo;
+
+#ifdef SUPPORT_BWF
+typedef struct
+{
+ unsigned char description[256];
+ unsigned char originator[32];
+ unsigned char originatorReference[32];
+ unsigned char originatorDate[10]; /* ASCII: <> */
+ unsigned char originationTime[8]; /* ASCII: <> */
+ unsigned int timeReferenceLow;
+ unsigned int timeReferenceHigh;
+ unsigned short version;
+ unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */
+
+ signed short loudnessVal;
+ signed short loudnessRange;
+ signed short maxTruePeakLevel;
+ signed short maxMomentaryLoudnes;
+ signed short maxShortTermLoudness;
+
+ unsigned char Reserved[180];
+
+ unsigned char codingHistory; /* ASCII: <> */
+} SBwfWav;
+#endif
+
+typedef struct
+{
+ char chunkID[4];
+ unsigned int chunkSize;
+ /* long dataOffset ; */ /* never used */
+} SChunk;
+
+/* local wrapper, always returns correct endian */
+static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream);
+
+#ifdef __TWI_BE
+static short BigEndian16(short v);
+static int BigEndian32(int v);
+#endif
+
+/*!
+ * \brief Read header from a WAVEfile. Host endianess is handled accordingly.
+ * \fp filepointer of type FILE*.
+ * \wavinfo SWavInfo struct where the decoded header info is stored into.
+ * \return 0 on success and non-zero on failure.
+ *
+ */
+static WAVEFILEIN *OpenWav(const char *filename, unsigned int *samplerate, short *channels, unsigned int *samplesInFile,
+ short *bps)
+{
+ WAVEFILEIN *self;
+
+ SChunk fmt_chunk, data_chunk;
+ int offset;
+ unsigned int tmpSize;
+ char tmpFormat[4];
+ SWavInfo wavinfo = {0, 0, 0, 0, 0, 0};
+
+ self = (WAVEFILEIN *)calloc(1, sizeof(WAVEFILEIN));
+ if (!self)
+ goto bail; /* return NULL; */
+
+ if (!filename)
+ goto bail;
+ if (!samplerate)
+ goto bail;
+ if (!channels)
+ goto bail;
+ if (!samplesInFile)
+ goto bail;
+ if (!bps)
+ goto bail;
+
+ self->theFile = fopen(filename, "rb");
+ if (!self->theFile)
+ goto bail;
+
+ /* read RIFF-chunk */
+ if (fread(tmpFormat, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+ if (strncmp("RIFF", tmpFormat, 4))
+ {
+ goto bail;
+ }
+
+ /* Read RIFF size. Ignored. */
+ fread_LE(&tmpSize, 4, 1, self->theFile);
+
+ /* read WAVE-chunk */
+ if (fread(tmpFormat, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+ if (strncmp("WAVE", tmpFormat, 4))
+ {
+ goto bail;
+ }
+
+ /* read format/bext-chunk */
+ if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+#ifdef SUPPORT_BWF
+ /* test for bext-chunk */
+ if (!strncmp("bext", fmt_chunk.chunkID, 4))
+ {
+ /*unsigned int i;*/
+ unsigned int bextSize = 0;
+
+ if (fread_LE(&bextSize, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+ self->loudnessInfo = (WAVEIN_LOUDNESSINFO *)calloc(1, sizeof(WAVEIN_LOUDNESSINFO));
+
+ if (bextSize >= 602)
+ { /* minimum size bext-data, w/o 'CodingHistory' */
+ int i;
+ signed short readBuf = 0;
+ signed int nulbuf = 0;
+
+ /* first skip all descriptive data */
+ for (i = 0; i < 412; i++)
+ {
+ if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1)
+ {
+ goto bail;
+ }
+ bextSize -= 1;
+ }
+ /* second, read loudness data */
+ fread_LE(&readBuf, 2, 1, self->theFile);
+ bextSize -= 2;
+ self->loudnessInfo->loudnessVal = (float)readBuf * 0.01f;
+
+ fread_LE(&readBuf, 2, 1, self->theFile);
+ bextSize -= 2;
+ self->loudnessInfo->loudnessRange = (float)readBuf * 0.01f;
+
+ fread_LE(&readBuf, 2, 1, self->theFile);
+ bextSize -= 2;
+ self->loudnessInfo->maxTruePeakLevel = (float)readBuf * 0.01f;
+
+ fread_LE(&readBuf, 2, 1, self->theFile);
+ bextSize -= 2;
+ self->loudnessInfo->maxMomentaryLoudnes = (float)readBuf * 0.01f;
+
+ fread_LE(&readBuf, 2, 1, self->theFile);
+ bextSize -= 2;
+ self->loudnessInfo->maxShortTermLoudness = (float)readBuf * 0.01f;
+
+ /* skip reserved data */
+ for (i = 0; i < 180; i++)
+ {
+ if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1)
+ {
+ goto bail;
+ }
+ bextSize -= 1;
+ }
+ }
+
+ /* skip remaining data */
+ while (bextSize)
+ {
+ int nulbuf;
+ if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1)
+ {
+ goto bail;
+ }
+ bextSize -= 1;
+ }
+
+ /* read next chunk header */
+ if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+ }
+#endif
+
+ /* skip some potential chunks up to fmt chunk */
+
+ while (strncmp("fmt ", fmt_chunk.chunkID, 4) != 0)
+ {
+ unsigned int chunkSize = 0;
+
+ if (fread_LE(&chunkSize, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+ /* skip chunk data */
+ while (chunkSize)
+ {
+ int nulbuf;
+ if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1)
+ {
+ goto bail;
+ }
+ chunkSize -= 1;
+ }
+
+ /* read next chunk header */
+ if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+ }
+
+ /* go on with fmt-chunk */
+ if (strncmp("fmt ", fmt_chunk.chunkID, 4))
+ {
+ goto bail;
+ }
+
+ if (fread_LE(&fmt_chunk.chunkSize, 4, 1, self->theFile) != 1)
+ { /* should be 16 for PCM-format (uncompressed) */
+ goto bail;
+ }
+
+
+ /* read info */
+ fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile);
+ fread_LE(&(wavinfo.numberOfChannels), 2, 1, self->theFile);
+ fread_LE(&(wavinfo.sampleRate), 4, 1, self->theFile);
+ fread_LE(&(wavinfo.averageBytesPerSecond), 4, 1, self->theFile);
+ fread_LE(&(wavinfo.blockAlign), 2, 1, self->theFile);
+ fread_LE(&(wavinfo.bitsPerSample), 2, 1, self->theFile);
+
+ if (wavinfo.compressionCode == -2)
+ {
+ fseek(self->theFile, 8, SEEK_CUR); // skip channel mask
+ fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile); // part of GUID
+ fseek(self->theFile, 14, SEEK_CUR); // skip rest of GUID
+ offset = fmt_chunk.chunkSize - 40;
+ }
+ else
+ offset = fmt_chunk.chunkSize - 16;
+
+ if (wavinfo.compressionCode == 0x01)
+ {
+ if ((wavinfo.bitsPerSample != 16) && (wavinfo.bitsPerSample != 24) && (wavinfo.bitsPerSample != 32))
+ /* we do only support 16,24 and 32 bit PCM audio */
+ goto bail;
+ }
+ else
+ {
+ /* if(wavinfo.bitsPerSample != 32) */
+ printf("compressioncode: %02x\n", wavinfo.compressionCode);
+ puts("Error! We only support 16,24 and 32 bit PCM audio");
+ exit(1);
+ goto bail;
+ }
+
+ /* Skip rest of fmt header if any. */
+ for (; offset > 0; offset--)
+ {
+ fread(&tmpSize, 1, 1, self->theFile);
+ }
+
+ do
+ {
+
+ /* Read data chunk ID */
+ if (fread(data_chunk.chunkID, 1, 4, self->theFile) != 4)
+ {
+ goto bail;
+ }
+
+ /* Read chunk length. */
+
+ if (fread_LE(&offset, 4, 1, self->theFile) != 1)
+ {
+ goto bail;
+ }
+
+ /* Check for data chunk signature. */
+ if (strncmp("data", data_chunk.chunkID, 4) == 0)
+ {
+ data_chunk.chunkSize = offset;
+ break;
+ }
+
+ /* unused 1 byte present, if size is odd */
+ /* see https://www.daubnet.com/en/file-format-riff */
+ if (offset % 2)
+ {
+ offset++;
+ }
+
+ /* Jump over non data chunk. */
+ for (; offset > 0; offset--)
+ {
+ fread(&tmpSize, 1, 1, self->theFile);
+ }
+
+ } while (!feof(self->theFile));
+
+ /* success so far */
+ *samplerate = wavinfo.sampleRate;
+ *channels = wavinfo.numberOfChannels;
+ *samplesInFile = data_chunk.chunkSize / wavinfo.numberOfChannels;
+ *samplesInFile /= ((wavinfo.bitsPerSample + 7) / 8);
+ *bps = wavinfo.bitsPerSample;
+
+ self->position = 0;
+ self->bps = wavinfo.bitsPerSample;
+ self->length = *samplesInFile * wavinfo.numberOfChannels;
+
+ fgetpos(self->theFile, &self->dataChunkPos);
+
+ return self;
+
+bail:
+ free(self);
+ return NULL;
+}
+
+#ifdef SUPPORT_BWF
+static void ReadBWF(WAVEFILEIN *self, WAVEIN_LOUDNESSINFO **wavInLoudness)
+{
+ *wavInLoudness = self->loudnessInfo;
+}
+#endif
+
+static int __ReadSample16(WAVEFILEIN *self, int *sample)
+{
+ size_t cnt;
+ short v = 0;
+
+ cnt = fread(&v, 2, 1, self->theFile);
+
+ if (cnt != 1)
+ {
+ return __TWI_ERROR;
+ }
+
+ self->position += 1;
+
+#ifdef __TWI_BE
+ v = BigEndian16(v);
+#endif
+ *sample = v;
+ return __TWI_SUCCESS;
+}
+
+static int __ReadSample24(WAVEFILEIN *self, int *sample)
+{
+ size_t cnt;
+ int v = 0;
+
+ cnt = fread(&v, 3, 1, self->theFile);
+
+ if (cnt != 1)
+ {
+ return __TWI_ERROR;
+ }
+
+ self->position += 1;
+
+#ifdef __TWI_BE
+ v = BigEndian32(v);
+#endif
+
+ if (v >= 0x800000)
+ {
+ v |= 0xff000000;
+ }
+
+ *sample = v;
+
+ return __TWI_SUCCESS;
+}
+
+static int __ReadSample32(WAVEFILEIN *self, int *sample)
+{
+ size_t cnt;
+ int v = 0;
+
+ cnt = fread(&v, 4, 1, self->theFile);
+
+ if (cnt != 1)
+ {
+ return __TWI_ERROR;
+ }
+
+ self->position += 1;
+
+#ifdef __TWI_BE
+ v = BigEndian32(v);
+#endif
+
+ *sample = v >> 8;
+
+ return __TWI_SUCCESS;
+}
+
+static int __ReadSampleInternal(WAVEFILEIN *self, int *sample, int scale)
+{
+ int err;
+
+ if (!self)
+ {
+ return __TWI_ERROR;
+ }
+
+ switch (scale)
+ {
+
+ case 16: err = __ReadSample16(self, sample); break;
+
+ case 24: err = __ReadSample24(self, sample); break;
+
+ case 32: err = __ReadSample32(self, sample); break;
+
+ default: err = __TWI_ERROR; break;
+ }
+
+ return err;
+}
+
+/* this function returns normalized values in the range +8388607..-8388608 */
+static int ReadWavInt(WAVEFILEIN *self, int sampleBuffer[], unsigned int nSamplesToRead, unsigned int *nSamplesRead)
+{
+ unsigned int i;
+ int err = __TWI_SUCCESS;
+ *nSamplesRead = 0;
+
+ if (!sampleBuffer)
+ {
+ return __TWI_ERROR;
+ }
+
+ /* check if we have enough samples left, if not,
+ set nSamplesToRead to number of samples left. */
+ if (self->position + nSamplesToRead > self->length)
+ {
+ nSamplesToRead = self->length - self->position;
+ }
+
+ for (i = 0; i < nSamplesToRead; i++)
+ {
+
+ int tmp;
+ err = __ReadSampleInternal(self, &tmp, self->bps);
+ if (err != __TWI_SUCCESS)
+ {
+ return err;
+ }
+ sampleBuffer[i] = tmp;
+ *nSamplesRead += 1;
+ }
+
+ return __TWI_SUCCESS;
+}
+
+static int CloseWavIn(WAVEFILEIN *self)
+{
+ if (self)
+ {
+ if (self->theFile)
+ {
+ fclose(self->theFile);
+ }
+ }
+ free(self);
+
+ return __TWI_SUCCESS;
+}
+/*
+static int ResetWavIn(WAVEFILEIN* self)
+{
+ if (self) {
+ if (self->theFile) {
+ fsetpos(self->theFile, &self->dataChunkPos);
+ self->position = 0;
+ }
+ }
+ return __TWI_SUCCESS;
+}
+*/
+/*------------- local subs ----------------*/
+
+static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+#ifdef __TWI_LE
+ return fread(ptr, size, nmemb, stream);
+#endif
+#ifdef __TWI_BE
+
+ unsigned char x[sizeof(int)];
+ unsigned char *y = (unsigned char *)ptr;
+ int i;
+ int len;
+
+ len = fread(x, size, nmemb, stream);
+
+ for (i = 0; i < size * nmemb; i++)
+ {
+ *y++ = x[size * nmemb - i - 1];
+ }
+
+ return len;
+#endif
+}
+
+#ifdef __TWI_BE
+static short BigEndian16(short v)
+{
+ short a = (v & 0x0ff);
+ short b = (v & 0x0ff00) >> 8;
+
+ return a << 8 | b;
+}
+
+static int BigEndian32(int v)
+{
+ int a = (v & 0x0ff);
+ int b = (v & 0x0ff00) >> 8;
+ int c = (v & 0x0ff0000) >> 16;
+ int d = (v & 0xff000000) >> 24;
+
+ return a << 24 | b << 16 | c << 8 | d;
+}
+#endif
+
+#endif /* __TINYWAVEIN_C_H__ */
diff --git a/lib_lc3plus/tinywaveout_c.h b/lib_lc3plus/tinywaveout_c.h
new file mode 100644
index 0000000000000000000000000000000000000000..67225427097acbd130a6f03b725338666ca73ddd
--- /dev/null
+++ b/lib_lc3plus/tinywaveout_c.h
@@ -0,0 +1,889 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#ifndef __TINYWAVEOUT_C_H__
+#define __TINYWAVEOUT_C_H__
+
+/*#define TWO_SUPPORT_BWF*/
+
+#include
+#include
+#include
+#include
+#ifdef TWO_SUPPORT_BWF
+#include
+#endif
+
+/***** Interface *********************************************************/
+
+#ifndef TWO_UINT64
+ #if !(defined(WIN32))
+ #include
+ #define TWO_UINT64 uint64_t
+ #else
+ #define TWO_UINT64 unsigned __int64
+ #endif
+#endif
+
+typedef struct WAVEFILEOUT WAVEFILEOUT;
+#ifdef TWO_SUPPORT_BWF
+typedef struct WAVEOUT_LOUDNESSINFO WAVEOUT_LOUDNESSINFO;
+#endif
+
+#define __TWO_SUCCESS (0)
+#define __TWO_ERROR (-1)
+
+static WAVEFILEOUT* CreateWav(
+ const char *fileName,
+ const unsigned int sampleRate,
+ const unsigned int numChannels,
+ const unsigned int bps
+ );
+
+#ifdef TWO_SUPPORT_BWF
+static WAVEFILEOUT* CreateWavBWF(
+ const char *fileName,
+ const unsigned int sampleRate,
+ const unsigned int numChannels,
+ const unsigned int bps,
+ const WAVEOUT_LOUDNESSINFO *hBwfData
+ );
+#endif
+
+/* this function expects values in the 16 bit range +32767..-32768 */
+static int WriteWavShort(
+ WAVEFILEOUT* self,
+ short sampleBuffer[],
+ unsigned int nSamples
+ );
+
+/* this function expects values in the 24 bit range +8388607..-8388608 */
+static int WriteWavLong(
+ WAVEFILEOUT* self,
+ int sampleBuffer[],
+ unsigned int nSamples
+ );
+
+/* this function expects normalized values in the range +-1.0f */
+static int WriteWavFloat(
+ WAVEFILEOUT* self,
+ float sampleBuffer[],
+ unsigned int nSamples
+ );
+
+static int CloseWav(WAVEFILEOUT* self);
+#ifdef TWO_SUPPORT_BWF
+static int CloseWavBWF(WAVEFILEOUT* self, WAVEOUT_LOUDNESSINFO bextData);
+#endif
+
+/***** Implementation *********************************************************/
+
+#if defined (__i386__) || defined (_M_IX86) || defined (_M_X64) || defined (__x86_64__) || defined (__arm__) || defined (__xtensa__) || defined (__aarch64__) || defined (__EMSCRIPTEN__)
+#define __TWO_LE /* _T_iny _W_ave _O_ut _L_ittle _E_ndian */
+#endif
+
+#if defined (__POWERPC__)
+#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */
+#endif
+
+#if defined (__sparc__)
+#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */
+#endif
+
+#if ! defined (__TWO_LE) && ! defined (__TWO_BE)
+#error unknown processor
+#endif
+
+/*--- local types/structs ----------------------------------*/
+
+#if defined(_MSC_VER)
+ #pragma pack(push, 1)
+#else
+ #pragma pack(1)
+#endif
+
+
+#ifdef TWO_SUPPORT_BWF
+struct WAVEOUT_LOUDNESSINFO {
+ float loudnessVal;
+ float loudnessRange;
+ float maxTruePeakLevel;
+ float maxMomentaryLoudnes;
+ float maxShortTermLoudness;
+};
+#endif
+
+
+typedef struct __tinyWaveOutHeader
+{
+ unsigned int riffType; /* 'RIFF/RF64' */
+ unsigned int riffSize; /* file size/-1 */
+ unsigned int waveType; /* 'WAVE' */
+} __tinyWaveOutHeader;
+
+typedef struct __tinyWaveOutDs64Chunk
+{
+ unsigned int formatType; /* = 'JUNK/ds64' */
+ unsigned int formatSize; /* size info */
+ TWO_UINT64 riffSize64;
+ TWO_UINT64 dataSize64;
+ TWO_UINT64 sampleCount64;
+ unsigned int tableLength; /* optional tables, always 0 for tinywaveout */
+ /* here: optional tables */
+} __tinyWaveOutDs64Chunk;
+
+#ifdef TWO_SUPPORT_BWF
+typedef struct __tinyWaveOutBextChunk
+{
+ unsigned int formatType; /* = 'bext' */
+ unsigned int formatSize; /* size info */
+
+ unsigned char description[256];
+ unsigned char originator[32];
+ unsigned char originatorReference[32];
+ unsigned char originatorDate[10]; /* ASCII: <> */
+ unsigned char originationTime[8]; /* ASCII: <> */
+ unsigned int timeReferenceLow;
+ unsigned int timeReferenceHigh;
+ unsigned short version;
+ unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */
+
+ signed short loudnessVal;
+ signed short loudnessRange;
+ signed short maxTruePeakLevel;
+ signed short maxMomentaryLoudnes;
+ signed short maxShortTermLoudness;
+
+ unsigned char Reserved[180];
+
+ unsigned char codingHistory; /* ASCII: <> - undefined length! */
+ /* for variable length, mve this out of this struct */
+} __tinyWaveOutBextChunk;
+#endif
+
+typedef struct __tinyWaveOutFmtChunk
+{
+ unsigned int formatType;
+ unsigned int formatSize;
+
+ unsigned short formatTag;
+ unsigned short numChannels;
+ unsigned int sampleRate;
+ unsigned int bytesPerSecond;
+ unsigned short blockAlignment;
+ unsigned short bitsPerSample;
+
+ /* wav fmt ext hdr here */
+} __tinyWaveOutFmtChunk;
+
+typedef struct __tinyWaveOutDataChunk
+{
+ unsigned int dataType;
+ unsigned int dataSize;
+
+} __tinyWaveOutDataChunk;
+
+
+struct WAVEFILEOUT {
+ /* for reasons of memory alignment, have 64 bit data types first */
+ TWO_UINT64 dataSize;
+ TWO_UINT64 dataSizeLimit; /* maximum size for data chunk for 4 GB files */
+ TWO_UINT64 dataSizeLimit64; /* maximum size for data chunk for 2^64 B addressable files */
+ TWO_UINT64 clipCount;
+ FILE* theFile;
+ unsigned int junkChunkOffset;
+ unsigned int fmtChunkOffset;
+#ifdef TWO_SUPPORT_BWF
+ unsigned int bextChunkOffset;
+#endif
+ unsigned int dataChunkOffset;
+ unsigned int bps;
+
+ /* only needed for RF64: */
+ unsigned int blockAlign; /* only needed for close() of ds64 chunk */
+};
+
+
+/*--- local protos --------------------------------------------------*/
+static __inline unsigned int BigEndian32(char, char, char, char);
+static __inline unsigned int LittleEndian32(unsigned int);
+static __inline unsigned int LittleEndian32s(int);
+static __inline short LittleEndian16(short);
+static __inline TWO_UINT64 LittleEndian64(TWO_UINT64);
+#ifdef TWO_SUPPORT_BWF
+static unsigned int EncodeLoudness(float);
+#endif
+static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes );
+
+#if defined(_MSC_VER)
+ #pragma pack(pop)
+#else
+ #pragma pack()
+#endif
+
+
+#ifdef TWO_SUPPORT_BWF
+static void setDefaultLoudness(WAVEOUT_LOUDNESSINFO *x)
+{
+ x->loudnessVal = 1.0f;
+ x->loudnessRange = 2.0f;
+ x->maxTruePeakLevel = 3.0f;
+ x->maxMomentaryLoudnes = 4.0f;
+ x->maxShortTermLoudness = 5.0f;
+}
+#endif
+
+static WAVEFILEOUT* __CreateWavInternal(
+ const char *fileName,
+ const unsigned int sampleRate,
+ const unsigned int numChannels,
+ const unsigned int bps
+#ifdef TWO_SUPPORT_BWF
+ ,
+ const WAVEOUT_LOUDNESSINFO *hBwfData
+#endif
+ )
+{
+ WAVEFILEOUT* self = NULL;
+ __tinyWaveOutHeader whdr;
+ __tinyWaveOutDs64Chunk ds64ch;
+#ifdef TWO_SUPPORT_BWF
+ __tinyWaveOutBextChunk wbextch;
+#endif
+ __tinyWaveOutFmtChunk wfch;
+ __tinyWaveOutDataChunk wdch;
+ unsigned int blockAlignment = 0;
+ unsigned int ByteCnt = 0; /* Byte counter for fwrite */
+
+ /* pseudo use to avoid unused symbols */
+ (void)WriteWavShort;
+ (void)WriteWavLong;
+ (void)WriteWavFloat;
+#ifdef TWI_SUPPORT_BWF
+ (void)CreateWavBWF;
+ (void)CloseWavBWF;
+ (void)setDefaultLoudness;
+#endif
+
+ /* param check */
+ if (!fileName) goto bail;
+ if (sampleRate == 0) goto bail;
+ if (sampleRate > 768000) goto bail;
+ if (numChannels == 0) goto bail;
+ if (numChannels > 64) goto bail;
+ if (bps != 16 && bps != 24 && bps != 32) goto bail;
+
+ self = (WAVEFILEOUT*)calloc(1, sizeof(WAVEFILEOUT));
+ if (!self) goto bail; /* return NULL; */
+
+ self->theFile = fopen(fileName, "wb+");
+ if (!self->theFile) goto bail;
+
+ /* WAV-Header */
+ whdr.riffType = BigEndian32('R','I','F','F');
+ whdr.riffSize = LittleEndian32(0xffffffff); /* set to maximum, if fseek() doesn't work later */
+ whdr.waveType = BigEndian32('W','A','V','E');
+ /* write to file */
+ ByteCnt = 0;
+ ByteCnt += fwrite(&whdr, 1, sizeof(whdr), self->theFile);
+
+ /* ds64/JUNK-Chunk */
+ ds64ch.formatType = BigEndian32('J','U','N','K');
+ ds64ch.formatSize = LittleEndian32(sizeof(__tinyWaveOutDs64Chunk) - 8);
+ ds64ch.riffSize64 = (TWO_UINT64) -1;
+ ds64ch.dataSize64 = (TWO_UINT64) -1;
+ ds64ch.sampleCount64 = (TWO_UINT64) -1;
+ ds64ch.tableLength = 0;
+ self->junkChunkOffset = ByteCnt;
+ ByteCnt += fwrite(&ds64ch, 1, sizeof(ds64ch), self->theFile);
+
+#ifdef TWO_SUPPORT_BWF
+ /* BEXT-Chunk */
+ if (hBwfData) {
+ memset(&wbextch, 0, sizeof(__tinyWaveOutBextChunk));
+ wbextch.formatType = BigEndian32('b','e','x','t');
+ wbextch.formatSize = LittleEndian32(sizeof(__tinyWaveOutBextChunk) - 8);
+ wbextch.version = 0x0002;
+ wbextch.loudnessVal = EncodeLoudness(hBwfData->loudnessVal);
+ wbextch.loudnessRange = EncodeLoudness(hBwfData->loudnessRange);
+ wbextch.maxTruePeakLevel = EncodeLoudness(hBwfData->maxTruePeakLevel);
+ wbextch.maxMomentaryLoudnes = EncodeLoudness(hBwfData->maxMomentaryLoudnes);
+ wbextch.maxShortTermLoudness = EncodeLoudness(hBwfData->maxShortTermLoudness);
+ /* t.b.d.: more values */
+
+ /* write to file */
+ self->bextChunkOffset = ByteCnt;
+ ByteCnt += fwrite(&wbextch, 1, sizeof(wbextch), self->theFile);
+ }
+#endif
+
+ /* FMT-Chunk */
+ wfch.formatType = BigEndian32('f','m','t',' ');
+ wfch.formatSize = LittleEndian32(16);
+ switch (bps) {
+ case 16:
+ case 24:
+ wfch.formatTag = LittleEndian16(0x0001); /* WAVE_FORMAT_PCM */
+ break;
+ case 32:
+ wfch.formatTag = LittleEndian16(0x0003); /* WAVE_FORMAT_IEEE_FLOAT */
+ break;
+ default:
+ goto bail;
+ }
+ self->bps = bps;
+ wfch.bitsPerSample = LittleEndian16(bps);
+ wfch.numChannels = LittleEndian16(numChannels);
+ blockAlignment = numChannels * (bps >> 3);
+ wfch.blockAlignment = LittleEndian16(blockAlignment);
+ wfch.sampleRate = LittleEndian32(sampleRate);
+ wfch.bytesPerSecond = LittleEndian32(sampleRate * blockAlignment);
+ /* tbd: wavfmt ext hdr here */
+ /* write to file */
+ self->fmtChunkOffset = ByteCnt;
+ ByteCnt += fwrite(&wfch, 1, sizeof(wfch), self->theFile);
+
+ /* DATA-Chunk */
+ self->dataChunkOffset = ByteCnt;
+ wdch.dataType = BigEndian32('d','a','t','a');
+ wdch.dataSize = LittleEndian32(0xffffffff - ByteCnt); /* yet unknown. set to maximum of 4 GB file */
+ /* write to file */
+ ByteCnt += fwrite(&wdch, 1, sizeof(wdch), self->theFile);
+
+ self->dataSize = 0;
+
+ /* self->dataSizeLimit = 0x7fffffff - ByteCnt; */ /* maximum size for data chunk for 2 GB files */
+ self->dataSizeLimit = 0xffffffff - ByteCnt; /* maximum size for data chunk for 4 GB files */
+ self->dataSizeLimit64 = 0xffffffffffffffff - ByteCnt; /* maximum size for data chunk for 64 bit addressable files */
+
+ self->clipCount = 0;
+ self->blockAlign = blockAlignment;
+
+ return self;
+
+ bail:
+ if ( NULL != self) {
+ free(self);
+ }
+
+ return NULL;
+}
+
+static WAVEFILEOUT* CreateWav(
+ const char* fileName,
+ const unsigned int sampleRate,
+ const unsigned int numChannels,
+ const unsigned int bps
+ )
+{
+#ifdef TWO_SUPPORT_BWF
+ return __CreateWavInternal(fileName, sampleRate, numChannels, bps, NULL);
+#else
+ return __CreateWavInternal(fileName, sampleRate, numChannels, bps);
+#endif
+}
+
+#ifdef TWO_SUPPORT_BWF
+static WAVEFILEOUT* CreateWavBWF(
+ const char *fileName,
+ const unsigned int sampleRate,
+ const unsigned int numChannels,
+ const unsigned int bps,
+ const WAVEOUT_LOUDNESSINFO *hBwfData
+ )
+{
+ return __CreateWavInternal(fileName, sampleRate, numChannels, bps, hBwfData);
+}
+#endif
+
+#define MAX_PCM16 (+32767)
+#define MIN_PCM16 (-32768)
+static __inline int CLIP_PCM16(int sample, TWO_UINT64* clipcount)
+{
+ int tmp = sample;
+
+ if (sample >= MAX_PCM16) {
+ tmp = MAX_PCM16;
+ (*clipcount)++;
+ } else {
+ if (sample <= MIN_PCM16) {
+ tmp = MIN_PCM16;
+ (*clipcount)++;
+ }
+ }
+
+ return tmp;
+}
+
+#define MAX_PCM24 (+8388607)
+#define MIN_PCM24 (-8388608)
+static __inline int CLIP_PCM24(int sample, TWO_UINT64* clipcount)
+{
+ int tmp = sample;
+
+ if (sample >= MAX_PCM24) {
+ tmp = MAX_PCM24;
+ (*clipcount)++;
+ } else {
+ if (sample <= MIN_PCM24) {
+ tmp = MIN_PCM24;
+ (*clipcount)++;
+ }
+ }
+
+ return tmp;
+}
+
+#define MAX_FLOAT32 (+1.0f)
+#define MIN_FLOAT32 (-1.0f)
+static __inline float CLIP_FLOAT32(float sample, TWO_UINT64* clipcount)
+{
+ float tmp = sample;
+
+ if (sample >= MAX_FLOAT32) {
+ tmp = MAX_FLOAT32;
+ (*clipcount)++;
+ } else {
+ if (sample <= MIN_FLOAT32) {
+ tmp = MIN_FLOAT32;
+ (*clipcount)++;
+ }
+ }
+
+ return tmp;
+}
+
+
+
+static int __WriteSample16(
+ WAVEFILEOUT* self,
+ int sample,
+ int scale
+ )
+{
+ size_t cnt;
+ short v;
+
+ if ((scale - 16) > 0)
+ sample = sample >> (scale - 16);
+ else
+ sample = (int) ((uint32_t) sample << (16 - scale));
+
+ v = (short)CLIP_PCM16(sample, &(self->clipCount));
+#ifdef __TWO_BE
+ v = LittleEndian16(v);
+#endif
+
+ cnt = fwrite(&v, sizeof(short), 1, self->theFile);
+
+ if (cnt == 1) {
+ self->dataSize += 2;
+ return __TWO_SUCCESS;
+ }
+
+ return __TWO_ERROR;
+}
+
+
+static int __WriteSample24(
+ WAVEFILEOUT* self,
+ int sample,
+ int scale
+ )
+{
+ size_t cnt;
+ int v;
+
+ if ((scale - 24) > 0)
+ sample = sample >> (scale - 24);
+ else
+ sample = (int) (((unsigned int)sample) << (24 - scale));
+
+ v = (int)CLIP_PCM24(sample, &(self->clipCount));
+#ifdef __TWO_BE
+ v = LittleEndian32s(v);
+#endif
+ cnt = fwrite(&v, 3, 1, self->theFile);
+
+ if (cnt == 1) {
+ self->dataSize += 3;
+ return __TWO_SUCCESS;
+ }
+
+ return __TWO_ERROR;
+}
+
+
+static int __WriteSample32(
+ WAVEFILEOUT* self,
+ float sample
+ )
+{
+ size_t cnt;
+ union fl_int {
+ float v_float;
+ int v_int;
+ };
+ union fl_int v;
+
+#if CLIP_FLOAT
+ v.v_float = CLIP_FLOAT32(sample, &(self->clipCount));
+#else
+ v.v_float = sample;
+ if((sample > 1.0f) || (sample <-1.0f))
+ self->clipCount++;
+#endif
+
+#ifdef __TWO_BE
+ v.v_int = LittleEndian32s(v.v_int);
+#endif
+ cnt = fwrite(&v, 4, 1, self->theFile);
+
+ if (cnt == 1) {
+ self->dataSize += 4;
+ return __TWO_SUCCESS;
+ }
+
+ return __TWO_ERROR;
+}
+
+
+static int __WriteSampleInt(
+ WAVEFILEOUT* self,
+ int sample,
+ int scale
+ )
+{
+ int err;
+
+ if (!self) return __TWO_ERROR;
+
+
+ switch (self->bps) {
+
+ case 16:
+ err = __WriteSample16(self, sample, scale);
+ break;
+
+ case 24:
+ err = __WriteSample24(self, sample, scale);
+ break;
+
+ default:
+ err = __TWO_ERROR;
+ break;
+ }
+
+ return err;
+}
+
+
+/* this function expects values in the 16 bit range +-32767/8 */
+static int WriteWavShort(
+ WAVEFILEOUT* self,
+ short sampleBuffer[],
+ unsigned int nSamples
+ )
+{
+ unsigned long i;
+ int err = __TWO_SUCCESS;
+
+ if (!self) return __TWO_ERROR;
+ if (!sampleBuffer) return __TWO_ERROR;
+ if (__dataSizeChk(self, nSamples * sizeof(short))) return __TWO_ERROR;
+
+ for (i=0; i< nSamples; i++) {
+ if (self->bps == 32)
+ {
+ err = __WriteSample32(self, sampleBuffer[i] / 32768.0f);
+ }
+ else
+ {
+ err = __WriteSampleInt(self, (int)sampleBuffer[i], 16);
+ }
+ if (err != __TWO_SUCCESS) return err;
+ }
+
+ return __TWO_SUCCESS;
+}
+
+
+/* this function expects values in the 24 bit range +-8388607/8 */
+static int WriteWavLong(
+ WAVEFILEOUT* self,
+ int sampleBuffer[],
+ unsigned int nSamples
+ )
+{
+ unsigned long i;
+ int err = __TWO_SUCCESS;
+
+ if (!self) return __TWO_ERROR;
+ if (!sampleBuffer) return __TWO_ERROR;
+ if (__dataSizeChk(self, nSamples * sizeof(int))) return __TWO_ERROR;
+
+ for (i = 0; i < nSamples; i++) {
+ if (self->bps == 32)
+ {
+ err = __WriteSample32(self, sampleBuffer[i] / 8388608.0f);
+ }
+ else
+ {
+ err = __WriteSampleInt(self, sampleBuffer[i], 24);
+ }
+ if (err != __TWO_SUCCESS) return err;
+ }
+
+ return __TWO_SUCCESS;
+}
+
+
+/* this function expects normalized values in the range +-1.0 */
+#define MAX_FL (+2.0f * 8388608.0f )
+#define MIN_FL (-2.0f * 8388608.0f )
+#define CLIP_FL(x) ( ((x) >= MAX_FL) ? MAX_FL : (((x) <= MIN_FL) ? MIN_FL : (x)) )
+static int WriteWavFloat(
+ WAVEFILEOUT* self,
+ float sampleBuffer[],
+ unsigned int nSamples
+ )
+{
+ unsigned int i;
+ int err = __TWO_SUCCESS;
+
+ if (!self) return __TWO_ERROR;
+ if (!sampleBuffer) return __TWO_ERROR;
+ if (__dataSizeChk(self, nSamples * sizeof(float))) return __TWO_ERROR;
+
+ for (i=0; ibps == 32)
+ {
+ err = __WriteSample32(self, sampleBuffer[i]);
+ }
+ else
+ {
+ float tmp = CLIP_FL(sampleBuffer[i] * 8388608.0f); /* CLIP_FL is just to avoid an INT overrun before the actual cast to int, real clipping and counting is done below */
+ err = __WriteSampleInt(self, (int) tmp, 24);
+ }
+ if (err != __TWO_SUCCESS) return err;
+ }
+
+ return __TWO_SUCCESS;
+}
+
+
+static int CloseWav(WAVEFILEOUT* self)
+{
+ unsigned int riffSize_le = 0;
+ unsigned int dataSize_le = 0;
+ TWO_UINT64 riffSize64 = 0;
+ TWO_UINT64 dataSize64 = 0;
+ TWO_UINT64 sampleCount64 = 0; /* nr of samples in the WAVE sense: 1 sample are all pcm samples of all channels of one time slice */
+ int mustWriteRF64 = 0;
+
+ if (!self) return __TWO_ERROR;
+
+ /* check for 4 GB (switch to RF64) */
+ if ( self->dataSize > self->dataSizeLimit ) {
+ /* when we exceed 4 GB: switch from std wave header to RF64 header */
+ mustWriteRF64 = 1;
+ }
+
+ /* calc header values */
+ if (mustWriteRF64 == 0) {
+ /* write padding byte if dataSize is uneven */
+ int pad = 0;
+ if (self->dataSize % 2 > 0) {
+ char tmp= 0x00;
+ fwrite(&tmp, sizeof(char), 1, self->theFile);
+ pad = 1;
+ }
+ riffSize_le = LittleEndian32(self->dataChunkOffset - 8 + 8 + (unsigned int)self->dataSize + pad); /* sizeof(hdr) - (8 bytes of riff chunk header) + (8 bytes data chunk header) + sizeof(raw-pcm-data) + padding Byte */
+ dataSize_le = LittleEndian32((unsigned int)self->dataSize);
+ } else {
+ riffSize_le = 0xffffffff;
+ dataSize_le = 0xffffffff;
+ riffSize64 = LittleEndian64( self->dataSize + (TWO_UINT64)self->dataChunkOffset );
+ dataSize64 = LittleEndian64( self->dataSize );
+ sampleCount64 = LittleEndian64( self->dataSize / (TWO_UINT64)self->blockAlign );
+ }
+
+ /* now overwrite length/size values in header with the actual/real ones */
+ if (mustWriteRF64 == 0) {
+ /* riffsize32 */
+ fseek(self->theFile, 4, SEEK_SET);
+ fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile);
+ /* datasize32 */
+ fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET);
+ fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile);
+ } else {
+ unsigned int rf64sig = BigEndian32('R','F','6','4');
+ unsigned int ds64sig = BigEndian32('d','s','6','4');
+
+ /* replace RIFF->RF64 */
+ fseek(self->theFile, 0, SEEK_SET);
+ fwrite(&rf64sig, sizeof(rf64sig), 1, self->theFile);
+
+ /* riffsize32 */
+ fseek(self->theFile, 4, SEEK_SET);
+ fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile);
+
+ /* replace JUNK->ds64 */
+ fseek(self->theFile, self->junkChunkOffset, SEEK_SET);
+ fwrite(&ds64sig, sizeof(ds64sig), 1, self->theFile);
+
+ /* riffSize64, dataSize64, sampleCount64 */
+ fseek(self->theFile, self->junkChunkOffset + 8, SEEK_SET);
+ fwrite(&riffSize64, sizeof(riffSize64), 1, self->theFile);
+ fwrite(&dataSize64, sizeof(dataSize64), 1, self->theFile);
+ fwrite(&sampleCount64, sizeof(sampleCount64), 1, self->theFile);
+
+ /* datasize32 */
+ fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET);
+ fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile);
+ }
+
+ fclose(self->theFile);
+ free(self);
+
+ return __TWO_SUCCESS;
+}
+
+#ifdef TWO_SUPPORT_BWF
+static int CloseWavBWF(
+ WAVEFILEOUT* self,
+ WAVEOUT_LOUDNESSINFO bextData
+ )
+{
+ int wordData;
+
+ if (!self) return __TWO_ERROR;
+
+ if (self->bextChunkOffset) {
+ /* Offset for Loudness Data in bext-chunk: 8: Chunk-Header, 412:prev.Data */
+ fseek(self->theFile, self->bextChunkOffset+8+412, SEEK_SET);
+
+ wordData = LittleEndian32(EncodeLoudness(bextData.loudnessVal));
+ fwrite(&wordData, 2, 1, self->theFile);
+
+ wordData = LittleEndian32(EncodeLoudness(bextData.loudnessRange));
+ fwrite(&wordData, 2, 1, self->theFile);
+
+ wordData = LittleEndian32(EncodeLoudness(bextData.maxTruePeakLevel));
+ fwrite(&wordData, 2, 1, self->theFile);
+
+ wordData = LittleEndian32(EncodeLoudness(bextData.maxMomentaryLoudnes));
+ fwrite(&wordData, 2, 1, self->theFile);
+
+ wordData = LittleEndian32(EncodeLoudness(bextData.maxShortTermLoudness));
+ fwrite(&wordData, 2, 1, self->theFile);
+ }
+
+ return CloseWav(self);
+}
+#endif
+
+/*------------- local subs ----------------*/
+
+static __inline unsigned int BigEndian32(char a, char b, char c, char d)
+{
+#ifdef __TWO_LE
+ return
+ (unsigned int) d << 24 |
+ (unsigned int) c << 16 |
+ (unsigned int) b << 8 |
+ (unsigned int) a ;
+#else
+ return
+ (unsigned int) a << 24 |
+ (unsigned int) b << 16 |
+ (unsigned int) c << 8 |
+ (unsigned int) d ;
+#endif
+}
+
+
+static __inline unsigned int LittleEndian32(unsigned int v)
+{
+#ifdef __TWO_LE
+ return v;
+#else
+ return
+ (v & 0x000000FF) << 24 |
+ (v & 0x0000FF00) << 8 |
+ (v & 0x00FF0000) >> 8 |
+ (v & 0xFF000000) >> 24 ;
+#endif
+}
+
+
+/* signed version of the above */
+static __inline unsigned int LittleEndian32s(int v)
+{
+#ifdef __TWO_LE
+ return v;
+#else
+ return
+ (v & 0x000000FF) << 24 |
+ (v & 0x0000FF00) << 8 |
+ (v & 0x00FF0000) >> 8 |
+ (v & 0xFF000000) >> 24 ;
+#endif
+}
+
+
+static __inline short LittleEndian16(short v)
+{
+#ifdef __TWO_LE
+ return v;
+#else
+ return ((v << 8) & 0xFF00) | ((v >> 8) & 0x00FF);
+#endif
+}
+
+static __inline TWO_UINT64 LittleEndian64(TWO_UINT64 v)
+{
+#ifdef __TWO_LE
+ return v;
+#else
+ return
+ (v & 0x00000000000000FF) << 56 |
+ (v & 0x000000000000FF00) << 40 |
+ (v & 0x0000000000FF0000) << 24 |
+ (v & 0x00000000FF000000) << 8 |
+ (v & 0x000000FF00000000) >> 8 |
+ (v & 0x0000FF0000000000) >> 24 |
+ (v & 0x00FF000000000000) >> 40 |
+ (v & 0xFF00000000000000) >> 56 ;
+#endif
+}
+
+#ifdef TWO_SUPPORT_BWF
+static unsigned int EncodeLoudness(float x)
+{
+ int s = (x>0)-(x<0);
+ return (int)( x*100.0f + s*0.5f );
+}
+#endif
+
+static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes )
+{
+ if (!self) return __TWO_ERROR;
+
+ if ( (self->dataSize + ((TWO_UINT64)newbytes) ) > self->dataSizeLimit64 ) {
+ return __TWO_ERROR;
+ }
+
+ return __TWO_SUCCESS;
+}
+
+#endif /* __TINYWAVEOUT_C_H__ */
+
+
+
diff --git a/lib_lc3plus/tns_coder_fx.c b/lib_lc3plus/tns_coder_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..640e246cc7b42a83b1550f899bb4470105372bd4
--- /dev/null
+++ b/lib_lc3plus/tns_coder_fx.c
@@ -0,0 +1,378 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order);
+static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order);
+static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */);
+
+/*************************************************************************/
+
+void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[],
+ Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms,
+ Word16 maxLen, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+ , Word16 near_nyquist_flag
+)
+{
+ Dyn_Mem_Deluxe_In(Word16 * tmpbuf; Word32 * rxx, epsP, *state, L_tmp, *A, predictionGain, alpha; Word16 * RC, inv;
+ Word16 n, n2, headroom, shift, tmp, shifts, facs, facs_e, stopfreq, xLen, maxOrder;
+ Word16 startfreq[TNS_NUMFILTERS_MAX]; const Word16 *subdiv_startfreq, *subdiv_stopfreq;
+ Counter i, j, iSubdivisions, lag; Word8 * LevinsonBuffer;);
+
+ /* Buffer alignment */
+ tmpbuf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */
+
+ rxx = (Word32 *)scratchAlign(tmpbuf, sizeof(*tmpbuf) * maxLen); /* Size = 4 * (MAXLAG + 1) = 36 bytes */
+
+ state = (Word32 *)scratchAlign(rxx, sizeof(*rxx) * (MAXLAG + 1)); /* Size = 4 * MAXLAG = 32 bytes */
+
+ A = (Word32 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = 4 * (MAXLAG + 1) = 36 bytes */
+
+ RC = (Word16 *)scratchAlign(A, sizeof(*A) * (MAXLAG + 1)); /* Size = 2 * MAXLAG = 16 bytes */
+
+ LevinsonBuffer = (Word8 *)scratchAlign(RC, sizeof(*RC) * (MAXLAG)); /* Size = 4 * (M_LTPF + 1) = 100 bytes */
+
+ /* Init */
+ *bits = 0;
+ move16();
+ maxOrder = MAXLAG;
+ move16();
+ *numfilters = 1;
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ xLen = BW_cutoff_bin_all_HR[BW_cutoff_idx];
+ }
+ else
+#endif
+ {
+ xLen = BW_cutoff_bin_all[BW_cutoff_idx];
+ }
+ move16();
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ startfreq[0] = 3;
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ subdiv_startfreq = tns_subdiv_startfreq_2_5ms_HR[BW_cutoff_idx - 4];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms_HR[BW_cutoff_idx - 4];
+ move16();
+ }
+ else
+#endif
+ {
+ subdiv_startfreq = tns_subdiv_startfreq_2_5ms[BW_cutoff_idx];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms[BW_cutoff_idx];
+ move16();
+ }
+ xLen = shr_pos(xLen, 2);
+ maxOrder = 4;
+ move16();
+ BREAK;
+ case 50:
+ startfreq[0] = 6;
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ subdiv_startfreq = tns_subdiv_startfreq_5ms_HR[BW_cutoff_idx - 4];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_5ms_HR[BW_cutoff_idx - 4];
+ move16();
+ }
+ else
+#endif
+ {
+ subdiv_startfreq = tns_subdiv_startfreq_5ms[BW_cutoff_idx];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_5ms[BW_cutoff_idx];
+ move16();
+ }
+ xLen = shr_pos(xLen, 1);
+ maxOrder = 4;
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ startfreq[0] = 9;
+ move16();
+ subdiv_startfreq = tns_subdiv_startfreq_7_5ms[BW_cutoff_idx];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_7_5ms[BW_cutoff_idx];
+ move16();
+ tmp = shr_pos(xLen, 2);
+ xLen = add(tmp, add(tmp, tmp));
+ maxOrder = 8;
+ BREAK;
+#endif
+ default: /* 100 */
+ startfreq[0] = 12;
+ move16();
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode)
+ {
+ subdiv_startfreq = tns_subdiv_startfreq_HR[BW_cutoff_idx - 4];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq_HR[BW_cutoff_idx - 4];
+ move16();
+ }
+ else
+#endif
+ {
+ subdiv_startfreq = tns_subdiv_startfreq[BW_cutoff_idx];
+ move16();
+ subdiv_stopfreq = tns_subdiv_stopfreq[BW_cutoff_idx];
+ move16();
+ }
+ BREAK;
+ }
+
+ IF (sub(BW_cutoff_idx, 3) >= 0 && frame_dms >= 50)
+ {
+ *numfilters = 2;
+ startfreq[1] = shr_pos(xLen, 1);
+ }
+
+ basop_memset(state, 0, MAXLAG * sizeof(*state));
+
+ FOR (j = 0; j < *numfilters; j++)
+ {
+ basop_memset(rxx, 0, (maxOrder + 1) * sizeof(*rxx));
+
+ FOR (iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++)
+ {
+ n = sub(subdiv_stopfreq[nSubdivisions * j + iSubdivisions],
+ subdiv_startfreq[nSubdivisions * j + iSubdivisions]);
+
+ /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/
+ headroom = getScaleFactor32_lc3plus(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], n);
+
+ /* Calculate norm of spectrum band */
+ L_tmp = Norm32Norm(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], headroom, n, &shift);
+
+ /* Rounding to avoid overflow when computing the autocorrelation below */
+ tmp = sub(norm_l(L_tmp), 1);
+ L_tmp = L_shl(L_tmp, tmp);
+ shift = sub(shift, tmp);
+ L_tmp = L_add(L_tmp, 0x8000);
+ L_tmp = L_and(L_tmp, 0x7FFF0000);
+
+ IF (L_tmp == 0)
+ {
+ rxx[0] = 0x7FFFFFFF;
+ move32();
+ basop_memset(&rxx[1], 0, (maxOrder) * sizeof(*rxx));
+ BREAK;
+ }
+
+ /* get pre-shift for autocorrelation */
+ tmp = sub(shift, norm_l(L_tmp)); /* exponent for normalized L_tmp */
+ tmp = shr_pos(sub(1, tmp), 1); /* pre-shift to apply before autocorrelation */
+ shifts = s_min(tmp, headroom);
+
+ /* calc normalization factor */
+ facs_e = shl_pos(sub(tmp, shifts), 1);
+
+ SWITCH (frame_dms)
+ {
+ case 25: facs_e = add(facs_e, 1); BREAK;
+ case 50: facs_e = add(facs_e, 1); BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75: BREAK;
+#endif
+ case 100: BREAK;
+ }
+
+ tmp = sub(1, shl_pos(tmp, 1)); /* exponent of autocorrelation */
+ L_tmp = L_shl(L_tmp, sub(shift, tmp)); /* shift L_tmp to that exponent */
+ /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */
+ facs = div_s(0x2000, round_fx(L_tmp)); /* L_tmp is >= 0x2000000 */
+
+ FOR (i = 0; i < n; i++)
+ {
+ tmpbuf[i] = round_fx_sat(L_shl_sat(x[subdiv_startfreq[nSubdivisions * j + iSubdivisions] + i], shifts));
+ move16();
+ }
+
+ FOR (lag = 0; lag <= maxOrder; lag++)
+ {
+ n2 = sub(n, lag);
+ L_tmp = L_deposit_l(0);
+ FOR (i = 0; i < n2; i++)
+ {
+ L_tmp = L_mac0(L_tmp, tmpbuf[i], tmpbuf[i + lag]);
+ }
+ if (lag != 0)
+ L_tmp = Mpy_32_32_lc3plus(L_tmp, tnsAcfWindow_lc3plus[lag - 1]);
+
+ L_tmp = Mpy_32_16_lc3plus(L_tmp, facs);
+ L_tmp = L_shl(L_tmp, facs_e);
+
+ rxx[lag] = L_add(rxx[lag], L_tmp);
+ move32();
+ }
+ }
+
+ /* Levinson-Durbin */
+ processLevinson_fx(A, rxx, maxOrder, RC, &epsP, LevinsonBuffer);
+
+ /* Prediction Gain */
+ shift = norm_l(epsP);
+ inv = div_s(16383, extract_h(L_shl_pos(epsP, shift)));
+ predictionGain = Mpy_32_32_lc3plus(rxx[0], Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(L_shl(epsP, shift), inv)), inv));
+
+ IF (L_sub(predictionGain, L_shr_pos_pos(0x30000000, shift)) > 0 && near_nyquist_flag == 0)
+ {
+ /* If Prediction Gain is low */
+ test();
+ IF (enable_lpc_weighting != 0 && L_sub(predictionGain, L_shr_pos_pos(0x40000000, shift)) < 0)
+ {
+ /* LPC weighting */
+ alpha = L_add(0x6CCCCCCD,
+ Mpy_32_32_lc3plus(0x13333333, L_shl_pos(L_sub(L_shl_pos(predictionGain, shift), 0x30000000), 3)));
+ L_tmp = alpha;
+ FOR (i = 1; i < maxOrder; i++)
+ {
+ A[i] = Mpy_32_32_lc3plus(A[i], L_tmp);
+ move32();
+ L_tmp = Mpy_32_32_lc3plus(L_tmp, alpha);
+ }
+ A[maxOrder] = Mpy_32_32_lc3plus(A[maxOrder], L_tmp);
+ move32();
+
+ /* LPC -> RC */
+ lpc2rc(A, RC, maxOrder);
+ }
+
+ /* Reflection Coefficients Quantization */
+ Parcor2Index(RC, &indexes[MAXLAG * j], maxOrder);
+
+ /* reduce filter order by truncating trailing zeros */
+ i = sub(maxOrder, 1);
+ WHILE ((i >= 0) && (indexes[MAXLAG * j + i] == INDEX_SHIFT))
+ {
+ i = sub(i, 1);
+ }
+ order[j] = add(i, 1);
+
+ // Disable TNS if order is 0:
+ IF (order[j] == 0) {
+ // Jump to else statement
+ goto tns_disabled;
+ }
+ /* Count bits */
+ L_tmp = L_deposit_l(ac_tns_order_bits[enable_lpc_weighting][order[j] - 1]);
+ FOR (i = 0; i < order[j]; i++)
+ {
+ L_tmp = L_add(L_tmp, L_deposit_l(ac_tns_coef_bits[i][indexes[MAXLAG * j + i]]));
+ }
+ *bits = add(*bits, add(2, extract_l(L_shr_pos(L_sub(L_tmp, 1), 11))));
+ move16();
+
+ /* Unquantize Reflection Coefficients */
+ Index2Parcor(&indexes[MAXLAG * j], RC, order[j]);
+
+ /* Stop frequency */
+ stopfreq = xLen;
+ move16();
+ IF (sub(*numfilters, 2) == 0 && j == 0)
+ {
+ stopfreq = startfreq[1];
+ }
+
+ /* Filter */
+ FOR (i = startfreq[j]; i < stopfreq; i++)
+ {
+ x[i] = FIRLattice(order[j], RC, state, x[i]);
+ move32();
+ }
+ }
+ ELSE
+ {
+tns_disabled:
+ /* TNS disabled */
+ *bits = add(*bits, 1);
+ order[j] = 0;
+ }
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*************************************************************************/
+
+static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order)
+{
+ Dyn_Mem_Deluxe_In(Counter i; Word16 iIndex; Word16 x;);
+
+ FOR (i = 0; i < order; i++)
+ {
+ move16();
+ move16();
+ iIndex = 1;
+ x = parCoeff[i];
+
+ WHILE ((iIndex < TNS_COEF_RES) && (x > tnsQuantThr[iIndex - 1]))
+ {
+ iIndex = add(iIndex, 1);
+ }
+ index[i] = sub(iIndex, 1);
+ move16();
+ }
+
+ Dyn_Mem_Deluxe_Out();
+}
+
+static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order)
+{
+ Counter i;
+ FOR (i = 0; i < order; i++)
+ {
+ parCoeff[i] = tnsQuantPts[index[i]];
+ move16();
+ }
+}
+
+static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */)
+{
+ Dyn_Mem_Deluxe_In(Counter i; Word32 tmpSave, tmp;);
+
+ tmpSave = L_add(x, 0);
+
+ FOR (i = 0; i < order - 1; i++)
+ {
+ tmp = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i]));
+ x = L_add(x, Mpy_32_16_lc3plus(state[i], parCoeff[i])); /* exponent: 31+0 */
+ state[i] = tmpSave;
+ move32();
+ tmpSave = L_add(tmp, 0);
+ }
+
+ /* last stage: only need half operations */
+ x = L_add(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1]));
+ state[order - 1] = tmpSave;
+ move32();
+ Dyn_Mem_Deluxe_Out();
+ return x;
+}
+
diff --git a/lib_lc3plus/tns_decoder_fx.c b/lib_lc3plus/tns_decoder_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..b138c451034c09ea1eb23c262fec6678d0290737
--- /dev/null
+++ b/lib_lc3plus/tns_decoder_fx.c
@@ -0,0 +1,150 @@
+/******************************************************************************
+* ETSI TS 103 634 V1.4.5 *
+* Low Complexity Communication Codec Plus (LC3plus) *
+* *
+* Copyright licence is solely granted through ETSI Intellectual Property *
+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
+* estoppel or otherwise. *
+******************************************************************************/
+
+#include "functions.h"
+
+static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x);
+
+/*************************************************************************/
+
+void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx,
+ Word16 frame_dms, Word8 *scratchBuffer
+#ifdef ENABLE_HR_MODE
+ , Word16 hrmode
+#endif
+)
+{
+ Dyn_Mem_Deluxe_In(
+ Word32 *state;
+ Counter i, j;
+ Word16 s1, s2, s, *rc, f, stopfreq, BW_stopband;
+ Word16 numfilters, startfreq[TNS_NUMFILTERS_MAX];
+ );
+
+ state = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = MAXLAG */
+ rc = (Word16 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = MAXLAG */
+
+ numfilters = 1;
+
+#ifdef ENABLE_HR_MODE
+ if (hrmode == 1)
+ {
+ BW_stopband = BW_cutoff_bin_all_HR[BW_stopband_idx]; move16();
+ }
+ else
+#endif
+ {
+ BW_stopband = BW_cutoff_bin_all[BW_stopband_idx]; move16();
+ }
+
+ SWITCH (frame_dms)
+ {
+ case 25:
+ startfreq[0] = 3; move16();
+ BW_stopband = shr_pos(BW_stopband, 2);
+ BREAK;
+ case 50:
+ startfreq[0] = 6; move16();
+ BW_stopband = shr_pos(BW_stopband, 1);
+ BREAK;
+#ifdef CR8_G_ADD_75MS
+ case 75:
+ startfreq[0] = 9; move16();
+ BW_stopband = add(shr_pos(BW_stopband, 2), add(shr_pos(BW_stopband, 2), shr_pos(BW_stopband, 2)));
+ BREAK;
+#endif
+ case 100: startfreq[0] = 12; BREAK;
+ }
+
+ IF (sub(BW_stopband_idx, 3) >= 0 && frame_dms >= 50)
+ {
+ numfilters = 2;
+ startfreq[1] = shr_pos(BW_stopband, 1);
+ }
+ stopfreq = 0;
+
+ test(); test();
+ IF (order[0] > 0 || (sub(numfilters, 2) == 0 && order[1] > 0))
+ {
+ /* Scaling */
+ f = startfreq[0]; move16();
+ test();
+ IF (sub(numfilters, 2) == 0 && order[0] == 0)
+ {
+ f = startfreq[1]; move16();
+ }
+ s1 = getScaleFactor32_lc3plus(x, f);
+ s2 = getScaleFactor32_lc3plus(x + f, sub(xLen, f));
+ s = s_min(s1, sub(s2, 7)); /* 7 bits of headroom for IIR filtering */
+ *x_e = sub(*x_e, s);
+
+/* Init Filter */
+ basop_memset(state, 0, MAXLAG * sizeof(Word32));
+ FOR (i = 0; i < f; i++)
+ {
+ x[i] = L_shl(x[i], s); move32();
+ }
+
+ FOR (j = 0; j < numfilters; j++)
+ {
+ IF (order[j] > 0)
+ {
+ /* Unquantize coefficients */
+ FOR (i = 0; i < order[j]; i++)
+ {
+ rc[i] = tnsQuantPts[rc_idx[j * MAXLAG + i]]; move16();
+ }
+
+ /* Stop frequency */
+ stopfreq = BW_stopband; move16();
+ IF (sub(numfilters, 2) == 0 && j == 0)
+ {
+ stopfreq = startfreq[1];
+ }
+
+ /* Filter */
+ FOR (i = startfreq[j]; i < stopfreq; i++)
+ {
+ x[i] = IIRLattice(order[j], rc, state, L_shl(x[i], s)); move32();
+ }
+ }
+ }
+ FOR (i = stopfreq; i < xLen; i++)
+ {
+ x[i] = L_shl(x[i], s); move32();
+ }
+ }
+ Dyn_Mem_Deluxe_Out();
+}
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x)
+{
+ Dyn_Mem_Deluxe_In(
+ Counter i;
+ );
+
+ /* first stage: no need to calculate state[order-1] */
+ x = L_sub_sat(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1]));
+
+ FOR (i = order - 2; i >= 0; i--)
+ {
+ x = L_sub(x, Mpy_32_16_lc3plus(state[i], parCoeff[i]));
+ state[i + 1] = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); move32();
+ }
+
+ state[0] = x; move32();
+
+ Dyn_Mem_Deluxe_Out();
+ return x;
+}
+
diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h
index 4afd38886bbb90e2aaa4a856708e9314958a1870..4a62de19f5db5155066ba7eb3b00fe5954069e2b 100644
--- a/lib_rend/ivas_prot_rend.h
+++ b/lib_rend/ivas_prot_rend.h
@@ -89,52 +89,6 @@ ivas_error get_channel_config(
#endif
-/*----------------------------------------------------------------------------------*
- * Limiter prototypes
- *----------------------------------------------------------------------------------*/
-
-
-ivas_error ivas_limiter_open(
- IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */
- const int16_t num_channels, /* i : number of I/O channels */
- const int32_t sampling_rate /* i : sampling rate for processing */
-);
-
-void ivas_limiter_close(
- IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */
-);
-
-void ivas_limiter_dec
-(
- IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
- float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
- const int16_t num_channels, /* i : number of channels to be processed */
- const int16_t output_frame, /* i : number of samples per channel in the buffer */
- const int16_t BER_detect /* i : BER detect flag */
-);
-void ivas_limiter_dec_fx(
- IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
- Word32 *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
- const Word16 num_channels, /* i : number of channels to be processed */
- const Word16 output_frame, /* i : number of samples per channel in the buffer */
- const Word16 BER_detect, /* i : BER detect flag */
- Word16 q_factor /* i : Q factor of the output samples */
-);
-void limiter_process(
- IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
- const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
- const float threshold, /* i : signal amplitude above which limiting starts to be applied */
- const int16_t BER_detect, /* i : BER detect flag */
- int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */
-);
-void limiter_process_fx(
- IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
- const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
- const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */
- const Word16 BER_detect, /* i : BER detect flag */
- Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations (can be NULL) */
- Word16 q_factor /* i : Q factor of output samples */
-);
/*----------------------------------------------------------------------------------*
* TD decorr. function prototypes
*----------------------------------------------------------------------------------*/
@@ -1620,26 +1574,6 @@ void ivas_headTrack_close_fx(
HEAD_TRACK_DATA_HANDLE *hHeadTrackData /* i/o: head track handle */
);
-void Euler2Quat(
- const float yaw, /* i : yaw (x) */
- const float pitch, /* i : pitch (y) */
- const float roll, /* i : roll (z) */
- IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
-);
-void Euler2Quat_fx(
- const Word32 yaw, /* i : yaw (x) Q22 */
- const Word32 pitch, /* i : pitch (y) Q22 */
- const Word32 roll, /* i : roll (z) Q22 */
- IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
-);
-float deg2rad(
- float degrees
-);
-
-Word32 deg2rad_fx(
- Word32 degrees
-);
-
float rad2deg(
float radians
);
diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c
index 758d787b196e56b0322c732312da721657e5d3b5..8b938a7e0f21df56bff0f2acd8ebf6646fd2fa18 100644
--- a/lib_rend/ivas_rotation.c
+++ b/lib_rend/ivas_rotation.c
@@ -239,53 +239,6 @@ void QuatToRotMat_fx(
}
-void Euler2Quat_fx(
- const Word32 yaw, /* i : yaw (x) Q22 */
- const Word32 pitch, /* i : pitch (y) Q22 */
- const Word32 roll, /* i : roll (z) Q22 */
- IVAS_QUATERNION *quat /* o : quaternion describing the rotation Q19 */
-)
-{
- Word16 cr = getCosWord16( extract_l( L_shr_r( roll, 10 ) ) ); // Q14
- Word16 sr = getSinWord16( extract_l( L_shr_r( roll, 10 ) ) );
- Word16 cp = getCosWord16( extract_l( L_shr_r( pitch, 10 ) ) );
- Word16 sp = getSinWord16( extract_l( L_shr_r( pitch, 10 ) ) );
- Word16 cy = getCosWord16( extract_l( L_shr_r( yaw, 10 ) ) );
- Word16 sy = getSinWord16( extract_l( L_shr_r( yaw, 10 ) ) );
- quat->w_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( cr, cp ), cy ), Mpy_32_16_1( L_mult0( sr, sp ), sy ) ), 5 ); // Q19
- move32();
- quat->x_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( sr, cp ), cy ), Mpy_32_16_1( L_mult0( cr, sp ), sy ) ), 5 ); // Q19
- move32();
- quat->y_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( sr, cp ), sy ), Mpy_32_16_1( L_mult0( cr, sp ), cy ) ), 5 ); // Q19
- move32();
- quat->z_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( cr, cp ), sy ), Mpy_32_16_1( L_mult0( sr, sp ), cy ) ), 5 ); // Q19
- move32();
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * deg2rad()
- *
- * Converts degrees to normalized radians
- *------------------------------------------------------------------------*/
-Word32 deg2rad_fx(
- Word32 degrees // Q23
-)
-{
- WHILE( GE_32( degrees, DEGREE_180 ) )
- {
- degrees = L_sub( degrees, DEGREE_360 );
- }
- WHILE( LE_32( degrees, -DEGREE_180 ) )
- {
- degrees = L_add( degrees, DEGREE_360 );
- }
-
- return Mpy_32_32( PI_OVER_180_FX, degrees ); // Q23
-}
-
/*-------------------------------------------------------------------------
* rad2deg()
*
diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h
index 38b2fe524c84a9eaccd902770f6fd8e5637c9afe..15381d5bd9a593bed3f975acfa38204958db5ec5 100644
--- a/lib_rend/ivas_stat_rend.h
+++ b/lib_rend/ivas_stat_rend.h
@@ -664,9 +664,16 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx
Word32 ***filterTapsRightReal_fx;
Word32 ***filterTapsRightImag_fx;
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ Word32 ****filterStatesLeftReal_fx;
+ Word32 ****filterStatesLeftImag_fx;
+ Word16 ****Q_filterStatesLeft;
+#else
Word32 ***filterStatesLeftReal_fx;
Word32 ***filterStatesLeftImag_fx;
Word16 ***Q_filterStatesLeft;
+#endif
+
Word16 numTapsArray[BINAURAL_CONVBANDS];
Word16 numTaps;
diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h
index 74e6070b529551c010c4cbe84c022487be01fe5e..5af21427f5f242c9da6651d70b63e074e7082961 100644
--- a/lib_rend/lib_rend.h
+++ b/lib_rend/lib_rend.h
@@ -55,20 +55,6 @@
typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS];
typedef Word32 IVAS_REND_LfePanMtx_fx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS];
-typedef struct
-{
- Word16 numSamplesPerChannel;
- Word16 numChannels;
-} IVAS_REND_AudioBufferConfig;
-typedef struct
-{
- IVAS_REND_AudioBufferConfig config;
- Word16 q_factor;
- Word16 *pq_fact;
- Word32 *data_fx;
- // Word16 Q_data;
-} IVAS_REND_AudioBuffer;
-
typedef struct
{