diff --git a/lib_com/options.h b/lib_com/options.h index 3f26853b0b0ea611a14181d5920394c884a25a1a..aa2bbfdd3fc1a5f4dea125e647ec8577bfd1a7a1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -206,6 +206,11 @@ #define NONBE_FIX_973_HODIRAC_BAND_GROUPING /* FhG: issue 973: empty parameter band in DirAC */ #define FIX_971_LOG2_IDX_GAIN_0 /* VA: prevent -Inf due to log2(ratio==0) */ +#define BE_FIX_567_DOUBLE_STEREO_DMX /* NTT: Fix formal issues */ +#define NONBE_FIX_567_DOUBLE_STEREO_DMX /* Orange: Double-precision replaced by single-precision */ +#define NONBE_FIX_947_STEREO_DMX_EVS_POC /* Orange: Fix clicks on POC */ +#define NONBE_FIX_947_STEREO_DMX_EVS_PHA /* Orange: Fix issues on PHA */ + /* #################### End BASOP porting switches ############################ */ /* clang-format on */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 745028ee16365b4d22fda6f374eb379f04e4d918..e79530df0f74df103f6f73cef5661b87fe40770b 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -132,6 +132,13 @@ float inv_sqrt( const float x /* i : input value */ ); +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX +/*! r: inverse square root of input value (float) */ +float inv_sqrtf( + const float x /* i : input value */ +); +#endif + /*! r: output random value */ int16_t own_random( int16_t *seed /* i/o: random seed */ diff --git a/lib_com/tools.c b/lib_com/tools.c index 8631bbc153e151d8e9aae0d66f8c76157e9459e6..04874fdd61c23f9feaeef885efd5fc27e305fb14 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -768,6 +768,21 @@ float inv_sqrt( return (float) ( 1.0 / sqrt( x ) ); } +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX +/*---------------------------------------------------------------------* + * inv_sqrtf() + * + * Find the inverse square root of the input value (float) + *---------------------------------------------------------------------*/ + +/*! r: inverse square root of input value (float) */ +float inv_sqrtf( + const float x /* i : input value */ +) +{ + return ( 1.0f / sqrtf( x ) ); +} +#endif /*-------------------------------------------------------------------* * conv() diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 1ab20a2ee8da89fbe648a039aea4a0bce45af550..1dc33478e8a2c51cd9d54e7703295a5095774b96 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -37,8 +37,8 @@ * Complexity counting tool *--------------------------------------------------------------------*/ -#define MAX_FUNCTION_NAME_LENGTH 200 /* Maximum length of the function name */ -#define MAX_PARAMS_LENGTH 200 /* Maximum length of the function parameter string */ +#define MAX_FUNCTION_NAME_LENGTH 200 /* Maximum length of the function name */ +#define MAX_PARAMS_LENGTH 200 /* Maximum length of the function parameter string */ #define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> might be increased during runtime, if needed */ #define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */ #define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */ @@ -46,7 +46,7 @@ #define FAC ( FRAMES_PER_SECOND / 1e6 ) -typedef struct +typedef struct { char label[MAX_FUNCTION_NAME_LENGTH]; long call_number; @@ -58,7 +58,7 @@ typedef struct double max_selfcnt; double min_selfcnt; double tot_selfcnt; - double start_cnt; + double start_cnt; double current_cnt; double max_cnt; double min_cnt; @@ -105,7 +105,7 @@ void reset_wmops( void ) /* allocate the list of wmops records */ if ( wmops == NULL ) { - wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) ); + wmops = (wmops_record *) malloc( max_num_wmops_records * sizeof( wmops_record ) ); } if ( wmops == NULL ) @@ -155,8 +155,8 @@ void reset_wmops( void ) #endif /* clear all BASOP operation counters */ - ptr = (unsigned int*) &multiCounter[i]; - for ( j = 0; j < (int) ( sizeof(BASIC_OP ) / sizeof( unsigned int ) ); j++ ) + ptr = (unsigned int *) &multiCounter[i]; + for ( j = 0; j < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); j++ ) { *ptr++ = 0; } @@ -263,7 +263,6 @@ void push_wmops_fct( const char *label, ... ) } wmops[i].LastWOper = 0; } - } strcpy( wmops[index_record].label, func_name ); @@ -331,7 +330,7 @@ void pop_wmops( void ) tot = DeltaWeightedOperation(); ops_cnt += tot; - /* update count of current record */ + /* update count of current record */ wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt; @@ -484,8 +483,8 @@ void print_wmops( void ) char *sfmts = "%*s %8s %8s %7s %7s\n"; char *dfmts = "%*s %8.2f %8.3f %7.3f %7.3f\n"; - char *sfmt = "%*s %8s %8s %7s %7s %7s %7s %7s\n"; - char *dfmt = "%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + char *sfmt = "%*s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; #ifdef WMOPS_WC_FRAME_ANALYSIS int j; @@ -506,7 +505,7 @@ void print_wmops( void ) max_label_len += 4; fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" ); - + fprintf( stdout, "%*s %33s %23s\n", max_label_len, "", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); fprintf( stdout, sfmt, max_label_len, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); fprintf( stdout, sfmt, max_label_len, "---------------", "------", "------", "------", "------", "------", "------", "------" ); @@ -528,7 +527,7 @@ void print_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); - fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); + fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); for ( i = 0; i < num_wmops_records; i++ ) @@ -562,7 +561,7 @@ void print_wmops( void ) fprintf( stdout, "\n\n" ); - fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); + fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); for ( i = 0; i < NUM_INST; i++ ) { switch ( (enum instructions) i ) @@ -685,7 +684,7 @@ void print_wmops( void ) #define BLOCK_ROUNDING 4 /* Align on 32 Bits */ #endif -#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) +#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) #define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) #define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */ @@ -704,7 +703,7 @@ typedef struct int16_t *stack_ptr; } caller_info; -static caller_info *stack_callers[2] = {NULL, NULL}; +static caller_info *stack_callers[2] = { NULL, NULL }; static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ @@ -939,7 +938,7 @@ int push_stack( const char *filename, const char *fctname ) /* save the worst-case frame number */ /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ - wc_stack_frame = update_cnt; + wc_stack_frame = update_cnt; strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 ); location_max_stack[sizeof( location_max_stack ) - 1] = '\0'; @@ -2172,13 +2171,13 @@ long TotalWeightedOperation() { int i; unsigned int *ptr, *ptr2; - long tot; + long tot; tot = 0; ptr = (unsigned int *) &multiCounter[currCounter]; ptr2 = (unsigned int *) &op_weight; - for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) + for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) { tot += ( ( *ptr++ ) * ( *ptr2++ ) ); } @@ -2217,5 +2216,3 @@ void Reset_BASOP_WMOPS_counter( void ) } #endif - - diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 42110465e0cf675cf631dddb44010074631f85b2..64eec1c15e74017e06507fc254c1e6422747f713 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -33,8 +33,8 @@ #define INT_MAX 32767 #endif -#define FRAMES_PER_SECOND 50.0 -#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ +#define FRAMES_PER_SECOND 50.0 +#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ #ifdef WMOPS enum instructions @@ -723,7 +723,7 @@ static int wmc_flag_ = 0; #define frexp_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexp ) #define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf ) -/* the macros below are instrumented versions of user-defined macros that might be used in the source code +/* the macros below are instrumented versions of user-defined macros that might be used in the source code /* representing some well-known and recognized mathematical operations (that are not defined in math.h) */ /* Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ @@ -1020,8 +1020,8 @@ int push_stack( const char *filename, const char *fctname ); int pop_stack( const char *filename, const char *fctname ); #ifdef WMOPS_DETAIL -#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ -#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ #else #define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) #define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ ) @@ -1177,20 +1177,20 @@ extern BASIC_OP *multiCounter; extern int currCounter; /* Technical note : - * The following 3 variables are only used for correct complexity - * evaluation of the following structure : - * IF{ - * ... - * } ELSE IF { - * ... - * } ELSE IF { - * ... - * } - * ... - * } ELSE { - * ... - * } - */ + * The following 3 variables are only used for correct complexity + * evaluation of the following structure : + * IF{ + * ... + * } ELSE IF { + * ... + * } ELSE IF { + * ... + * } + * ... + * } ELSE { + * ... + * } + */ extern int funcId_where_last_call_to_else_occurred; extern long funcid_total_wmops_at_last_call_to_else; extern int call_occurred; @@ -1217,15 +1217,20 @@ void Reset_BASOP_WMOPS_counter( void ); * *****************************************************************************/ #ifndef WMOPS -#define FOR( a) for( a) +#define FOR( a ) for ( a ) -#else -#define FOR( a) if( incrFor(), 0); else for( a) +#else +#define FOR( a ) \ + if ( incrFor(), 0 ) \ + ; \ + else \ + for ( a ) -static __inline void incrFor( void) { - multiCounter[currCounter].For++; +static __inline void incrFor( void ) +{ + multiCounter[currCounter].For++; } -#endif +#endif /***************************************************************************** @@ -1242,15 +1247,16 @@ static __inline void incrFor( void) { * *****************************************************************************/ #ifndef WMOPS -#define WHILE( a) while( a) +#define WHILE( a ) while ( a ) -#else -#define WHILE( a) while( incrWhile(), a) +#else +#define WHILE( a ) while ( incrWhile(), a ) -static __inline void incrWhile( void) { - multiCounter[currCounter].While++; +static __inline void incrWhile( void ) +{ + multiCounter[currCounter].While++; } -#endif +#endif /***************************************************************************** @@ -1267,10 +1273,10 @@ static __inline void incrWhile( void) { #ifndef WMOPS #define DO do -#else +#else #define DO do -#endif +#endif /***************************************************************************** @@ -1294,16 +1300,17 @@ static __inline void incrWhile( void) { * *****************************************************************************/ #ifndef WMOPS -#define IF( a) if( a) +#define IF( a ) if ( a ) -#else -#define IF( a) if( incrIf(), a) +#else +#define IF( a ) if ( incrIf(), a ) -static __inline void incrIf( void) { - /* Technical note : - * If the "IF" operator comes just after an "ELSE", its counter - * must not be incremented. - */ +static __inline void incrIf( void ) +{ + /* Technical note : + * If the "IF" operator comes just after an "ELSE", its counter + * must not be incremented. + */ if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) { multiCounter[currCounter].If++; @@ -1312,7 +1319,7 @@ static __inline void incrIf( void) { call_occurred = 0; funcId_where_last_call_to_else_occurred = INT_MAX; } -#endif +#endif /***************************************************************************** @@ -1329,27 +1336,30 @@ static __inline void incrIf( void) { #ifndef WMOPS #define ELSE else -#else -#define ELSE else if( incrElse(), 0) ; else +#else +#define ELSE \ + else if ( incrElse(), 0 ); \ + else -static __inline void incrElse( void) { - multiCounter[currCounter].If++; +static __inline void incrElse( void ) +{ + multiCounter[currCounter].If++; - /* We keep track of the funcId of the last function - * which used ELSE {...} structure. - */ - funcId_where_last_call_to_else_occurred = currCounter; + /* We keep track of the funcId of the last function + * which used ELSE {...} structure. + */ + funcId_where_last_call_to_else_occurred = currCounter; - /* We keep track of the number of WMOPS of this funcId - * when the ELSE macro was called. - */ - funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); + /* We keep track of the number of WMOPS of this funcId + * when the ELSE macro was called. + */ + funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); - /* call_occurred is set to 0, in order to count the next IF (if necessary) - */ - call_occurred = 0; + /* call_occurred is set to 0, in order to count the next IF (if necessary) + */ + call_occurred = 0; } -#endif +#endif /***************************************************************************** @@ -1364,15 +1374,16 @@ static __inline void incrElse( void) { * *****************************************************************************/ #ifndef WMOPS -#define SWITCH( a) switch( a) +#define SWITCH( a ) switch ( a ) -#else -#define SWITCH( a) switch( incrSwitch(), a) +#else +#define SWITCH( a ) switch ( incrSwitch(), a ) -static __inline void incrSwitch( void) { - multiCounter[currCounter].Switch++; +static __inline void incrSwitch( void ) +{ + multiCounter[currCounter].Switch++; } -#endif +#endif /***************************************************************************** @@ -1389,13 +1400,18 @@ static __inline void incrSwitch( void) { #ifndef WMOPS #define CONTINUE continue -#else -#define CONTINUE if( incrContinue(), 0); else continue +#else +#define CONTINUE \ + if ( incrContinue(), 0 ) \ + ; \ + else \ + continue -static __inline void incrContinue( void) { - multiCounter[currCounter].Continue++; +static __inline void incrContinue( void ) +{ + multiCounter[currCounter].Continue++; } -#endif +#endif /***************************************************************************** @@ -1412,13 +1428,18 @@ static __inline void incrContinue( void) { #ifndef WMOPS #define BREAK break -#else -#define BREAK if( incrBreak(), 0) break; else break +#else +#define BREAK \ + if ( incrBreak(), 0 ) \ + break; \ + else \ + break -static __inline void incrBreak( void) { - multiCounter[currCounter].Break++; +static __inline void incrBreak( void ) +{ + multiCounter[currCounter].Break++; } -#endif +#endif /***************************************************************************** @@ -1435,14 +1456,17 @@ static __inline void incrBreak( void) { #ifndef WMOPS #define GOTO goto -#else -#define GOTO if( incrGoto(), 0); else goto +#else +#define GOTO \ + if ( incrGoto(), 0 ) \ + ; \ + else \ + goto -static __inline void incrGoto( void) { - multiCounter[currCounter].Goto++; +static __inline void incrGoto( void ) +{ + multiCounter[currCounter].Goto++; } -#endif +#endif #endif /* WMOPS_H */ - - diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index eee7ba71d22042d91a845654fec0da4d9536a440..b9ea41c3f3c375ec9f839d8571037e423c600556 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -534,7 +534,114 @@ const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ - + #ifdef NONBE_FIX_947_STEREO_DMX_EVS_POC + + const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 1] = { + 0.00009518625f, 0.00038070876f, 0.00085645882f, 0.00152225529f, 0.00237784467f, 0.00342290120f, 0.00465702698f, 0.00607975212f, 0.00769053493f, 0.00948876211f, + 0.01147374899f, 0.01364473980f, 0.01600090794f, 0.01854135633f, 0.02126511768f, 0.02417115495f, 0.02725836167f, 0.03052556242f, 0.03397151320f, 0.03759490201f, + 0.04139434925f, 0.04536840829f, 0.04951556605f, 0.05383424350f, 0.05832279634f, 0.06297951556f, 0.06780262815f, 0.07279029773f, 0.07794062527f, 0.08325164980f, + 0.08872134919f, 0.09434764087f, 0.10012838266f, 0.10606137357f, 0.11214435465f, 0.11837500982f, 0.12475096680f, 0.13126979798f, 0.13792902134f, 0.14472610141f, + 0.15165845025f, 0.15872342839f, 0.16591834588f, 0.17324046329f, 0.18068699277f, 0.18825509907f, 0.19594190069f, 0.20374447091f, 0.21165983894f, 0.21968499105f, + 0.22781687170f, 0.23605238471f, 0.24438839446f, 0.25282172706f, 0.26134917154f, 0.26996748113f, 0.27867337446f, 0.28746353680f, 0.29633462133f, 0.30528325043f, + 0.31430601697f, 0.32339948556f, 0.33256019391f, 0.34178465414f, 0.35106935407f, 0.36041075859f, 0.36980531103f, 0.37924943444f, 0.38873953302f, 0.39827199347f, + 0.40784318636f, 0.41744946748f, 0.42708717932f, 0.43675265234f, 0.44644220647f, 0.45615215247f, 0.46587879332f, 0.47561842564f, 0.48536734113f, 0.49512182793f, + 0.50487817207f, 0.51463265887f, 0.52438157436f, 0.53412120668f, 0.54384784753f, 0.55355779353f, 0.56324734766f, 0.57291282068f, 0.58255053252f, 0.59215681364f, + 0.60172800653f, 0.61126046698f, 0.62075056556f, 0.63019468897f, 0.63958924141f, 0.64893064593f, 0.65821534586f, 0.66743980609f, 0.67660051444f, 0.68569398303f, + 0.69471674957f, 0.70366537867f, 0.71253646320f, 0.72132662554f, 0.73003251887f, 0.73865082846f, 0.74717827294f, 0.75561160554f, 0.76394761529f, 0.77218312830f, + 0.78031500895f, 0.78834016106f, 0.79625552909f, 0.80405809931f, 0.81174490093f, 0.81931300723f, 0.82675953671f, 0.83408165412f, 0.84127657161f, 0.84834154975f, + 0.85527389859f, 0.86207097866f, 0.86873020202f, 0.87524903320f, 0.88162499018f, 0.88785564535f, 0.89393862643f, 0.89987161734f, 0.90565235913f, 0.91127865081f, + 0.91674835020f, 0.92205937473f, 0.92720970227f, 0.93219737185f, 0.93702048444f, 0.94167720366f, 0.94616575650f, 0.95048443395f, 0.95463159171f, 0.95860565075f, + 0.96240509799f, 0.96602848680f, 0.96947443758f, 0.97274163833f, 0.97582884505f, 0.97873488232f, 0.98145864367f, 0.98399909206f, 0.98635526020f, 0.98852625101f, + 0.99051123789f, 0.99230946507f, 0.99392024788f, 0.99534297302f, 0.99657709880f, 0.99762215533f, 0.99847774471f, 0.99914354118f, 0.99961929124f, 0.99990481375f, + }; + + const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 1] = { + 0.00002394563f, 0.00009578022f, 0.00021549689f, 0.00038308417f, 0.00059852602f, 0.00086180179f, 0.00117288627f, 0.00153174967f, 0.00193835760f, 0.00239267114f, + 0.00289464674f, 0.00344423635f, 0.00404138732f, 0.00468604244f, 0.00537813998f, 0.00611761365f, 0.00690439261f, 0.00773840150f, 0.00861956044f, 0.00954778504f, + 0.01052298638f, 0.01154507106f, 0.01261394118f, 0.01372949435f, 0.01489162374f, 0.01610021802f, 0.01735516144f, 0.01865633380f, 0.02000361046f, 0.02139686238f, + 0.02283595610f, 0.02432075380f, 0.02585111325f, 0.02742688787f, 0.02904792673f, 0.03071407456f, 0.03242517178f, 0.03418105448f, 0.03598155450f, 0.03782649936f, + 0.03971571237f, 0.04164901255f, 0.04362621475f, 0.04564712957f, 0.04771156345f, 0.04981931865f, 0.05197019329f, 0.05416398135f, 0.05640047270f, 0.05867945313f, + 0.06100070434f, 0.06336400401f, 0.06576912578f, 0.06821583926f, 0.07070391012f, 0.07323310003f, 0.07580316675f, 0.07841386411f, 0.08106494204f, 0.08375614663f, + 0.08648722009f, 0.08925790085f, 0.09206792352f, 0.09491701895f, 0.09780491424f, 0.10073133278f, 0.10369599428f, 0.10669861478f, 0.10973890666f, 0.11281657874f, + 0.11593133621f, 0.11908288075f, 0.12227091048f, 0.12549512005f, 0.12875520064f, 0.13205083999f, 0.13538172244f, 0.13874752893f, 0.14214793710f, 0.14558262123f, + 0.14905125235f, 0.15255349823f, 0.15608902340f, 0.15965748923f, 0.16325855391f, 0.16689187254f, 0.17055709710f, 0.17425387653f, 0.17798185674f, 0.18174068066f, + 0.18552998825f, 0.18934941657f, 0.19319859978f, 0.19707716920f, 0.20098475333f, 0.20492097790f, 0.20888546587f, 0.21287783752f, 0.21689771045f, 0.22094469963f, + 0.22501841743f, 0.22911847365f, 0.23324447559f, 0.23739602804f, 0.24157273335f, 0.24577419148f, 0.25000000000f, 0.25424975414f, 0.25852304686f, 0.26281946885f, + 0.26713860858f, 0.27148005237f, 0.27584338436f, 0.28022818664f, 0.28463403922f, 0.28906052009f, 0.29350720527f, 0.29797366885f, 0.30245948302f, 0.30696421811f, + 0.31148744266f, 0.31602872341f, 0.32058762540f, 0.32516371195f, 0.32975654476f, 0.33436568391f, 0.33899068794f, 0.34363111384f, 0.34828651715f, 0.35295645195f, + 0.35764047095f, 0.36233812551f, 0.36704896567f, 0.37177254021f, 0.37650839670f, 0.38125608152f, 0.38601513994f, 0.39078511611f, 0.39556555316f, 0.40035599320f, + 0.40515597739f, 0.40996504598f, 0.41478273835f, 0.41960859304f, 0.42444214782f, 0.42928293972f, 0.43413050508f, 0.43898437958f, 0.44384409832f, 0.44870919580f, + 0.45357920605f, 0.45845366260f, 0.46333209856f, 0.46821404667f, 0.47309903931f, 0.47798660859f, 0.48287628638f, 0.48776760431f, 0.49266009390f, 0.49755328651f, + 0.50244671349f, 0.50733990610f, 0.51223239569f, 0.51712371362f, 0.52201339141f, 0.52690096069f, 0.53178595333f, 0.53666790144f, 0.54154633740f, 0.54642079395f, + 0.55129080420f, 0.55615590168f, 0.56101562042f, 0.56586949492f, 0.57071706028f, 0.57555785218f, 0.58039140696f, 0.58521726165f, 0.59003495402f, 0.59484402261f, + 0.59964400680f, 0.60443444684f, 0.60921488389f, 0.61398486006f, 0.61874391848f, 0.62349160330f, 0.62822745979f, 0.63295103433f, 0.63766187449f, 0.64235952905f, + 0.64704354805f, 0.65171348285f, 0.65636888616f, 0.66100931206f, 0.66563431609f, 0.67024345524f, 0.67483628805f, 0.67941237460f, 0.68397127659f, 0.68851255734f, + 0.69303578189f, 0.69754051698f, 0.70202633115f, 0.70649279473f, 0.71093947991f, 0.71536596078f, 0.71977181336f, 0.72415661564f, 0.72851994763f, 0.73286139142f, + 0.73718053115f, 0.74147695314f, 0.74575024586f, 0.75000000000f, 0.75422580852f, 0.75842726665f, 0.76260397196f, 0.76675552441f, 0.77088152635f, 0.77498158257f, + 0.77905530037f, 0.78310228955f, 0.78712216248f, 0.79111453413f, 0.79507902210f, 0.79901524667f, 0.80292283080f, 0.80680140022f, 0.81065058343f, 0.81447001175f, + 0.81825931934f, 0.82201814326f, 0.82574612347f, 0.82944290290f, 0.83310812746f, 0.83674144609f, 0.84034251077f, 0.84391097660f, 0.84744650177f, 0.85094874765f, + 0.85441737877f, 0.85785206290f, 0.86125247107f, 0.86461827756f, 0.86794916001f, 0.87124479936f, 0.87450487995f, 0.87772908952f, 0.88091711925f, 0.88406866379f, + 0.88718342126f, 0.89026109334f, 0.89330138522f, 0.89630400572f, 0.89926866722f, 0.90219508576f, 0.90508298105f, 0.90793207648f, 0.91074209915f, 0.91351277991f, + 0.91624385337f, 0.91893505796f, 0.92158613589f, 0.92419683325f, 0.92676689997f, 0.92929608988f, 0.93178416074f, 0.93423087422f, 0.93663599599f, 0.93899929566f, + 0.94132054687f, 0.94359952730f, 0.94583601865f, 0.94802980671f, 0.95018068135f, 0.95228843655f, 0.95435287043f, 0.95637378525f, 0.95835098745f, 0.96028428763f, + 0.96217350064f, 0.96401844550f, 0.96581894552f, 0.96757482822f, 0.96928592544f, 0.97095207327f, 0.97257311213f, 0.97414888675f, 0.97567924620f, 0.97716404390f, + 0.97860313762f, 0.97999638954f, 0.98134366620f, 0.98264483856f, 0.98389978198f, 0.98510837626f, 0.98627050565f, 0.98738605882f, 0.98845492894f, 0.98947701362f, + 0.99045221496f, 0.99138043956f, 0.99226159850f, 0.99309560739f, 0.99388238635f, 0.99462186002f, 0.99531395756f, 0.99595861268f, 0.99655576365f, 0.99710535326f, + 0.99760732886f, 0.99806164240f, 0.99846825033f, 0.99882711373f, 0.99913819821f, 0.99940147398f, 0.99961691583f, 0.99978450311f, 0.99990421978f, 0.99997605437f, + }; + + const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 1] = { + 0.00001066469f, 0.00004265829f, 0.00009597944f, 0.00017062587f, 0.00026659439f, 0.00038388092f, 0.00052248043f, 0.00068238703f, 0.00086359389f, 0.00106609329f, + 0.00128987657f, 0.00153493420f, 0.00180125573f, 0.00208882979f, 0.00239764411f, 0.00272768552f, 0.00307893994f, 0.00345139239f, 0.00384502699f, 0.00425982692f, + 0.00469577451f, 0.00515285116f, 0.00563103736f, 0.00613031272f, 0.00665065594f, 0.00719204483f, 0.00775445628f, 0.00833786630f, 0.00894225002f, 0.00956758164f, + 0.01021383449f, 0.01088098101f, 0.01156899272f, 0.01227784029f, 0.01300749347f, 0.01375792114f, 0.01452909129f, 0.01532097101f, 0.01613352653f, 0.01696672319f, + 0.01782052544f, 0.01869489686f, 0.01958980015f, 0.02050519713f, 0.02144104876f, 0.02239731512f, 0.02337395540f, 0.02437092795f, 0.02538819024f, 0.02642569887f, + 0.02748340959f, 0.02856127727f, 0.02965925593f, 0.03077729874f, 0.03191535800f, 0.03307338516f, 0.03425133082f, 0.03544914473f, 0.03666677580f, 0.03790417209f, + 0.03916128080f, 0.04043804831f, 0.04173442015f, 0.04305034103f, 0.04438575481f, 0.04574060451f, 0.04711483235f, 0.04850837971f, 0.04992118712f, 0.05135319434f, + 0.05280434026f, 0.05427456299f, 0.05576379980f, 0.05727198717f, 0.05879906076f, 0.06034495543f, 0.06190960523f, 0.06349294342f, 0.06509490245f, 0.06671541398f, + 0.06835440889f, 0.07001181725f, 0.07168756837f, 0.07338159076f, 0.07509381216f, 0.07682415952f, 0.07857255903f, 0.08033893610f, 0.08212321539f, 0.08392532077f, + 0.08574517538f, 0.08758270157f, 0.08943782098f, 0.09131045444f, 0.09320052209f, 0.09510794329f, 0.09703263668f, 0.09897452015f, 0.10093351086f, 0.10290952525f, + 0.10490247902f, 0.10691228715f, 0.10893886391f, 0.11098212284f, 0.11304197679f, 0.11511833788f, 0.11721111754f, 0.11932022649f, 0.12144557476f, 0.12358707169f, + 0.12574462591f, 0.12791814541f, 0.13010753744f, 0.13231270863f, 0.13453356489f, 0.13677001149f, 0.13902195302f, 0.14128929343f, 0.14357193598f, 0.14586978330f, + 0.14818273738f, 0.15051069953f, 0.15285357046f, 0.15521125022f, 0.15758363824f, 0.15997063331f, 0.16237213360f, 0.16478803667f, 0.16721823946f, 0.16966263830f, + 0.17212112893f, 0.17459360645f, 0.17707996539f, 0.17958009971f, 0.18209390273f, 0.18462126722f, 0.18716208538f, 0.18971624880f, 0.19228364855f, 0.19486417508f, + 0.19745771833f, 0.20006416764f, 0.20268341185f, 0.20531533920f, 0.20795983744f, 0.21061679373f, 0.21328609476f, 0.21596762663f, 0.21866127498f, 0.22136692487f, + 0.22408446091f, 0.22681376715f, 0.22955472717f, 0.23230722405f, 0.23507114037f, 0.23784635822f, 0.24063275922f, 0.24343022449f, 0.24623863471f, 0.24905787007f, + 0.25188781030f, 0.25472833469f, 0.25757932206f, 0.26044065079f, 0.26331219882f, 0.26619384366f, 0.26908546237f, 0.27198693160f, 0.27489812759f, 0.27781892614f, + 0.28074920265f, 0.28368883213f, 0.28663768917f, 0.28959564798f, 0.29256258237f, 0.29553836579f, 0.29852287128f, 0.30151597152f, 0.30451753885f, 0.30752744522f, + 0.31054556222f, 0.31357176111f, 0.31660591279f, 0.31964788784f, 0.32269755648f, 0.32575478862f, 0.32881945384f, 0.33189142141f, 0.33497056027f, 0.33805673909f, + 0.34114982620f, 0.34424968966f, 0.34735619724f, 0.35046921640f, 0.35358861436f, 0.35671425805f, 0.35984601412f, 0.36298374899f, 0.36612732880f, 0.36927661945f, + 0.37243148660f, 0.37559179565f, 0.37875741181f, 0.38192820002f, 0.38510402503f, 0.38828475135f, 0.39147024330f, 0.39466036500f, 0.39785498036f, 0.40105395309f, + 0.40425714674f, 0.40746442465f, 0.41067565002f, 0.41389068585f, 0.41710939500f, 0.42033164016f, 0.42355728386f, 0.42678618852f, 0.43001821639f, 0.43325322959f, + 0.43649109013f, 0.43973165987f, 0.44297480059f, 0.44622037393f, 0.44946824144f, 0.45271826458f, 0.45597030469f, 0.45922422305f, 0.46247988086f, 0.46573713923f, + 0.46899585921f, 0.47225590178f, 0.47551712789f, 0.47877939840f, 0.48204257416f, 0.48530651596f, 0.48857108456f, 0.49183614071f, 0.49510154512f, 0.49836715849f, + 0.50163284151f, 0.50489845488f, 0.50816385929f, 0.51142891544f, 0.51469348404f, 0.51795742584f, 0.52122060160f, 0.52448287211f, 0.52774409822f, 0.53100414079f, + 0.53426286077f, 0.53752011914f, 0.54077577695f, 0.54402969531f, 0.54728173542f, 0.55053175856f, 0.55377962607f, 0.55702519941f, 0.56026834013f, 0.56350890987f, + 0.56674677041f, 0.56998178361f, 0.57321381148f, 0.57644271614f, 0.57966835984f, 0.58289060500f, 0.58610931415f, 0.58932434998f, 0.59253557535f, 0.59574285326f, + 0.59894604691f, 0.60214501964f, 0.60533963500f, 0.60852975670f, 0.61171524865f, 0.61489597497f, 0.61807179998f, 0.62124258819f, 0.62440820435f, 0.62756851340f, + 0.63072338055f, 0.63387267120f, 0.63701625101f, 0.64015398588f, 0.64328574195f, 0.64641138564f, 0.64953078360f, 0.65264380276f, 0.65575031034f, 0.65885017380f, + 0.66194326091f, 0.66502943973f, 0.66810857859f, 0.67118054616f, 0.67424521138f, 0.67730244352f, 0.68035211216f, 0.68339408721f, 0.68642823889f, 0.68945443778f, + 0.69247255478f, 0.69548246115f, 0.69848402848f, 0.70147712872f, 0.70446163421f, 0.70743741763f, 0.71040435202f, 0.71336231083f, 0.71631116787f, 0.71925079735f, + 0.72218107386f, 0.72510187241f, 0.72801306840f, 0.73091453763f, 0.73380615634f, 0.73668780118f, 0.73955934921f, 0.74242067794f, 0.74527166531f, 0.74811218970f, + 0.75094212993f, 0.75376136529f, 0.75656977551f, 0.75936724078f, 0.76215364178f, 0.76492885963f, 0.76769277595f, 0.77044527283f, 0.77318623285f, 0.77591553909f, + 0.77863307513f, 0.78133872502f, 0.78403237337f, 0.78671390524f, 0.78938320627f, 0.79204016256f, 0.79468466080f, 0.79731658815f, 0.79993583236f, 0.80254228167f, + 0.80513582492f, 0.80771635145f, 0.81028375120f, 0.81283791462f, 0.81537873278f, 0.81790609727f, 0.82041990029f, 0.82292003461f, 0.82540639355f, 0.82787887107f, + 0.83033736170f, 0.83278176054f, 0.83521196333f, 0.83762786640f, 0.84002936669f, 0.84241636176f, 0.84478874978f, 0.84714642954f, 0.84948930047f, 0.85181726262f, + 0.85413021670f, 0.85642806402f, 0.85871070657f, 0.86097804698f, 0.86322998851f, 0.86546643511f, 0.86768729137f, 0.86989246256f, 0.87208185459f, 0.87425537409f, + 0.87641292831f, 0.87855442524f, 0.88067977351f, 0.88278888246f, 0.88488166212f, 0.88695802321f, 0.88901787716f, 0.89106113609f, 0.89308771285f, 0.89509752098f, + 0.89709047475f, 0.89906648914f, 0.90102547985f, 0.90296736332f, 0.90489205671f, 0.90679947791f, 0.90868954556f, 0.91056217902f, 0.91241729843f, 0.91425482462f, + 0.91607467923f, 0.91787678461f, 0.91966106390f, 0.92142744097f, 0.92317584048f, 0.92490618784f, 0.92661840924f, 0.92831243163f, 0.92998818275f, 0.93164559111f, + 0.93328458602f, 0.93490509755f, 0.93650705658f, 0.93809039477f, 0.93965504457f, 0.94120093924f, 0.94272801283f, 0.94423620020f, 0.94572543701f, 0.94719565974f, + 0.94864680566f, 0.95007881288f, 0.95149162029f, 0.95288516765f, 0.95425939549f, 0.95561424519f, 0.95694965897f, 0.95826557985f, 0.95956195169f, 0.96083871920f, + 0.96209582791f, 0.96333322420f, 0.96455085527f, 0.96574866918f, 0.96692661484f, 0.96808464200f, 0.96922270126f, 0.97034074407f, 0.97143872273f, 0.97251659041f, + 0.97357430113f, 0.97461180976f, 0.97562907205f, 0.97662604460f, 0.97760268488f, 0.97855895124f, 0.97949480287f, 0.98041019985f, 0.98130510314f, 0.98217947456f, + 0.98303327681f, 0.98386647347f, 0.98467902899f, 0.98547090871f, 0.98624207886f, 0.98699250653f, 0.98772215971f, 0.98843100728f, 0.98911901899f, 0.98978616551f, + 0.99043241836f, 0.99105774998f, 0.99166213370f, 0.99224554372f, 0.99280795517f, 0.99334934406f, 0.99386968728f, 0.99436896264f, 0.99484714884f, 0.99530422549f, + 0.99574017308f, 0.99615497301f, 0.99654860761f, 0.99692106006f, 0.99727231448f, 0.99760235589f, 0.99791117021f, 0.99819874427f, 0.99846506580f, 0.99871012343f, + 0.99893390671f, 0.99913640611f, 0.99931761297f, 0.99947751957f, 0.99961611908f, 0.99973340561f, 0.99982937413f, 0.99990402056f, 0.99995734171f, 0.99998933531f, + }; + + #else const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4] = { 0.00154133327f, 0.0138150426f, 0.0380602330f, 0.0736799166f, 0.119797014f, 0.175276011f, 0.238750681f, 0.308658302f, 0.383277327f, 0.460770488f, 0.539229512f, 0.616722703f, 0.691341758f, 0.761249363f, 0.824724138f, 0.880203009f, 0.926320136f, 0.961939812f, 0.986184955f, 0.998458624f, @@ -555,6 +662,7 @@ const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4] = { 0.761249363f, 0.783203125f, 0.804380774f, 0.824724138f, 0.844177306f, 0.862687230f, 0.880203009f, 0.896676719f, 0.912063122f, 0.926320136f, 0.939408541f, 0.951292694f, 0.961939812f, 0.971320748f, 0.979409873f, 0.986184955f, 0.991627395f, 0.995722473f, 0.998458624f, 0.999828696f }; +#endif const float Stereo_dmx_wnd_coef_32k[L_FRAME32k] = { 0.00245436677f, 0.00736304140f, 0.0122715384f, 0.0171797406f, 0.0220875274f, 0.0269947834f, 0.0319013894f, 0.0368072242f, 0.0417121723f, 0.0466161147f, diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 3d48dd2e400df1a0e055598a3664926a214ac9cf..a3bbf99d1d26647310f7580eaa884a183ab1d8fa 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -120,9 +120,15 @@ extern const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_POC +extern const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 1]; +extern const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 1]; +extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 1]; +#else extern const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4]; extern const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 4]; extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; +#endif extern const float Stereo_dmx_wnd_coef_32k[L_FRAME32k]; extern const float Stereo_dmx_wnd_coef_48k[L_FRAME48k]; diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 9eb39402f0fdb7e8c6f0a77324673aed9d6725e3..f6277d287b13abf7091fc00db512a56a0abedf08 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1078,7 +1078,9 @@ typedef struct stereo_dmx_evs_phase_only_correlation_structure typedef struct stereo_dmx_evs_correlation_filter_structure { +#ifndef NONBE_FIX_947_STEREO_DMX_EVS_PHA int16_t init_frmCntr; +#endif float isd_rate_s; float iccr_s; float ipd_ff[STEREO_DMX_EVS_NB_SUBBAND_MAX]; @@ -1099,17 +1101,44 @@ typedef struct stereo_dmx_evs_correlation_filter_structure STEREO_DMX_EVS_PHA curr_pha; STEREO_DMX_EVS_PHA prev_pha; int16_t pha_hys_cnt; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + STEREO_DMX_EVS_PHA proc_pha; + bool force_poc; + + int16_t pha_ipd_chan2rephase; + int16_t pha_ipd_previouschan2rephase; + int16_t pha_ipd_chan_cnt; + int16_t pha_ipd_chan_thresh; + float pha_ipd_ild_thresh; + int16_t pha_ipd_chanswitch; + int16_t pha_ipd_chanswitch_allowed; + float pha_ipd_sf_Threshold; +#endif int16_t prc_thres; STEREO_DMX_EVS_PRC curr_prc; STEREO_DMX_EVS_PRC prev_prc; int16_t prc_hys_cnt; float fad_g_prc[L_FRAME48k]; +#ifndef NONBE_FIX_947_STEREO_DMX_EVS_PHA int16_t fad_len_prc; +#endif float trns_aux_energy[CPE_CHANNELS]; float crst_fctr; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + int16_t n_fad_g; + int16_t n_fad_cnt; + float dmx_pha_ener; + float dmx_poc_ener; + float dmx_pha_ener_sgc; + float dmx_poc_ener_sgc; + float dmx_pha_gain_sgc; + float dmx_poc_gain_sgc; + float low_egy_thres_sgc; +#endif + } STEREO_DMX_EVS_PHA_DATA, *STEREO_DMX_EVS_PHA_HANDLE; typedef struct stereo_dmx_evs_enc_data_structure diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index 8b8a8663549f3094cd3bd90fca648a0f0be972f6..237ee8472178d77d2eb6b0c773a54766f95c2b57 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -58,7 +58,11 @@ #define STEREO_DMX_EVS_POC_FORGETTING 0.78f #define STEREO_DMX_EVS_TARGET_POC_FORGETTING 0.79f #define STEREO_DMX_EVS_POC_W_FORGETTING 0.875f -#define STEREO_DMX_EVS_SHIFT_LIMIT 5.625f /* ms */ +#ifdef BE_FIX_567_DOUBLE_STEREO_DMX +#define STEREO_DMX_EVS_SHIFT_LIMIT STEREO_DFT_ZP_NS_ENC +#else +#define STEREO_DMX_EVS_SHIFT_LIMIT 5.625f /* ms */ +#endif #define STEREO_DMX_EVS_DMX_EGY_FORGETTING 0.25f #define STEREO_DMX_EVS_CORR_FORGETTING 0.78f @@ -88,7 +92,14 @@ #define STEREO_DMX_EVS_SWTCH_PRC_THRES_48 29 #define STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES 1 -#define STEREO_DMX_EVS_FADE_LEN_PRC 20.0f +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA +#define STEREO_DMX_EVS_IFF_AMIN 0.857696f +#define STEREO_DMX_EVS_IFF_AMAX 0.944061f +#define STEREO_DMX_EVS_IFF_FREQ 3000.0f +#define STEREO_DMX_EVS_PHA_WND_C 1.8f +#else +#define STEREO_DMX_EVS_FADE_LEN_PRC 20.0f +#endif #define STEREO_DMX_EVS_NB_SBFRM 5 #define STEREO_DMX_EVS_TRNS_DTC_INST 75.0f @@ -97,7 +108,21 @@ #define STEREO_DMX_EVS_CRST_FCTR_48 35.0f #define STEREO_DMX_EVS_TRNS_EGY_FORGETTING 0.75f +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA +#define STEREO_DMX_EVS_FAD_R 3 +#define STEREO_DMX_EVS_SGC_EGY_FORGETTING 0.9f +#define STEREO_DMX_EVS_SGC_GR_S 1.00461543f +#define STEREO_DMX_EVS_SGC_GL 0.9885f +#define STEREO_DMX_EVS_SGC_GH 1.0116f +#define STEREO_DMX_EVS_SGC_LEGY_THRES_16 2.5E8 +#define STEREO_DMX_EVS_SGC_LEGY_THRES_32 3.E8 +#define STEREO_DMX_EVS_SGC_LEGY_THRES_48 5.E8 +#define STEREO_DMX_EVS_SGC_GMAX 1.4142f +#define STEREO_DMX_EVS_SGC_GMIN 0.7071f +#endif +#define STEREO_DMX_EVS_IPD_ILD_THRES 3.16f // 5dB +#define STEREO_DMX_EVS_IPD_SF_THRES 0.05f /*-----------------------------------------------------------------------* * Local function prototypes @@ -111,6 +136,9 @@ static void adapt_gain( const float src[], float dst[], const float gain, const static void create_M_signal( const float srcL[], const float srcR[], float dmx[], const float w_curr, const int16_t input_frame, const float wnd[], float *w_prev, float *dmx_energy, float *src_energy ); static float find_poc_peak( STEREO_DMX_EVS_POC_HANDLE hPOC, float itd[], const int16_t input_frame, const float ratio ); static void calc_energy( const float src1[], const float src2[], float energy[], const int16_t input_frame, const float ratio ); +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA +static float spectral_flatness( const float sig[], const int16_t sig_length ); +#endif /*-------------------------------------------------------------------* * estimate_itd_wnd_fft() @@ -202,7 +230,11 @@ static void calc_poc( int16_t cos_step, cos_max; float eps_cos, eps_sin, EPS; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + int16_t isd_cnt_h, isd_cnt_l, ild_cnt, n, freq_8k, freq_ipd_max, nsbd, input_frame_pha, pha_ipd_ild_chan2rephase; +#else int16_t isd_cnt_h, isd_cnt_l, ild_cnt, n, freq_8k, freq_ipd_max, nsbd, input_frame_pha; +#endif float Nr, Ni, Dr, Di, tPr, tPi, Pn, energy, isd_rate; float eneL, eneR, IPDr, IPDi, tIPDr, tIPDi, ICCr; float *Pr, *Pi, *ipd_ff, *p_curr_taps; @@ -381,12 +413,13 @@ static void calc_poc( } specPOr[n0] = sign( specLr[n0] * specRr[n0] ) * wnd[i * step + bias] * gamma; - +#ifndef NONBE_FIX_947_STEREO_DMX_EVS_PHA hPHA->init_frmCntr--; if ( hPHA->init_frmCntr < 0 ) { hPHA->init_frmCntr = 0; } +#endif freq_8k = L_FRAME16k / 2; freq_ipd_max = (int16_t) ( freq_8k * 5000.0f / ( 8000.0f * STEREO_DMX_EVS_SUBBAND_SIZE ) ); @@ -495,7 +528,11 @@ static void calc_poc( tPi += IPDi; /* ICCr */ +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + Pn = inv_sqrtf( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON ); +#else Pn = (float) inv_sqrt( ( IPDr * IPDr + IPDi * IPDi ) + EPSILON ); +#endif IPDr *= Pn; IPDi *= Pn; @@ -508,16 +545,37 @@ static void calc_poc( eneL += ( specLr[i] * specLr[i] + specLi[i] * specLi[i] ); eneR += ( specRr[i] * specRr[i] + specRi[i] * specRi[i] ); } - +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + Pn = inv_sqrtf( ( tPr * tPr + tPi * tPi ) + EPSILON ); +#else Pn = (float) inv_sqrt( ( tPr * tPr + tPi * tPi ) + EPSILON ); +#endif + tPr *= Pn; tPi *= Pn; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + + Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr; + Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi; +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + Pn = inv_sqrtf( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#else + Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#endif + Pr[n] *= Pn; + Pi[n] *= Pn; + +#else if ( hPHA->init_frmCntr == 0 ) { Pr[n] = ipd_ff[n] * Pr[n] + ( 1.0f - ipd_ff[n] ) * tPr; Pi[n] = ipd_ff[n] * Pi[n] + ( 1.0f - ipd_ff[n] ) * tPi; +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + Pn = inv_sqrtf( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#else Pn = (float) inv_sqrt( ( Pr[n] * Pr[n] + Pi[n] * Pi[n] ) + EPSILON ); +#endif Pr[n] *= Pn; Pi[n] *= Pn; } @@ -526,13 +584,264 @@ static void calc_poc( Pr[n] = tPr; Pi[n] = tPi; } - +#endif Pr[n] = ( Pr[n] > 1.0f ) ? 1.0f : Pr[n]; Pr[n] = ( Pr[n] < -1.0f ) ? -1.0f : Pr[n]; } + +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + /* Computes Spectral flatness on one channel */ + tmp1 = spectral_flatness( &tEl[1], nsbd - 1 ); + if ( tmp1 < hPHA->pha_ipd_sf_Threshold ) + { + hPHA->pha_ipd_chanswitch_allowed = 0; + } + else + { + hPHA->pha_ipd_chanswitch_allowed = 1; + } +#endif + +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + ICCr = sqrtf( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) ); +#else ICCr = (float) sqrt( ( Nr * Nr + Ni * Ni ) / ( eneL * eneR + EPSILON ) ); +#endif hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD ) + { + hPHA->force_poc = FALSE; + hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD; + } + else + { + if ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_L ) || ( ( hPHA->iccr_s < STEREO_DMX_EVS_ICCR_HYST_H ) && ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 ) && !hPHA->force_poc ) ) + { + hPHA->force_poc = FALSE; + hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD2; + } + else + { + hPHA->force_poc = TRUE; + } + } + + if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD ) + { + rfft_pha_buf[0] = 1.; + rfft_pha_buf[1] = 1.; + + ild_cnt = 0; + for ( i = 1; i < nsbd; i++ ) + { + rfft_pha_buf[i * 2] = Pr[i]; + rfft_pha_buf[i * 2 + 1] = Pi[i]; + if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) ) + { + ild_cnt++; + tEr[i] = 1; + } + else + { + tEr[i] = -1; + } + } + if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC ) + { + for ( i = 1; i < nsbd; i++ ) + { + if ( tEr[i] > 0 ) + { + rfft_pha_buf[i * 2] = 1.; + rfft_pha_buf[i * 2 + 1] = 0.; + } + } + } + + rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 ); + + /* Choose best channel to phase align */ + /* Channel selection based on ILD */ + if ( hPHA->trns_aux_energy[0] > hPHA->trns_aux_energy[1] * hPHA->pha_ipd_ild_thresh ) + { + pha_ipd_ild_chan2rephase = 0; + } + else if ( hPHA->trns_aux_energy[1] > hPHA->trns_aux_energy[0] * hPHA->pha_ipd_ild_thresh ) + { + pha_ipd_ild_chan2rephase = 1; + } + else + { + pha_ipd_ild_chan2rephase = -1; + } + + /* Channel selection based on spikyness of R2L/L2R impulse responses */ + tmp1 = spectral_flatness( rfft_pha_buf, hPHA->pha_len ); + rfft_pha_buf[input_frame_pha - hPHA->pha_len] = rfft_pha_buf[0]; + tmp2 = spectral_flatness( &rfft_pha_buf[input_frame_pha - hPHA->pha_len], hPHA->pha_len ); + + /* Combined ILD/SF channel selection with tempo */ + if ( ( ( tmp1 > tmp2 ) && ( pha_ipd_ild_chan2rephase == -1 ) ) || ( pha_ipd_ild_chan2rephase == 0 ) ) /* L => R */ + { + if ( hPHA->pha_ipd_previouschan2rephase == 0 ) + { + hPHA->pha_ipd_chan_cnt++; + if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh ) + { + /* Avoid channel switch in case of too harmonic signals */ + if ( hPHA->pha_ipd_chanswitch_allowed ) + { + if ( hPHA->pha_ipd_chan2rephase != 0 ) + { + hPHA->pha_ipd_chanswitch = 1; + } + else + { + hPHA->pha_ipd_chanswitch = 0; + } + hPHA->pha_ipd_chan2rephase = 0; + } + } + } + else + { + hPHA->pha_ipd_previouschan2rephase = 0; + hPHA->pha_ipd_chan_cnt = 1; + hPHA->pha_ipd_chanswitch = 0; + } + } + else /* R => L */ + { + if ( hPHA->pha_ipd_previouschan2rephase == 1 ) + { + hPHA->pha_ipd_chan_cnt++; + if ( hPHA->pha_ipd_chan_cnt >= hPHA->pha_ipd_chan_thresh ) + { + /* Avoid channel switch in case of too harmonic signals */ + if ( hPHA->pha_ipd_chanswitch_allowed ) + { + if ( hPHA->pha_ipd_chan2rephase != 1 ) + { + hPHA->pha_ipd_chanswitch = 1; + } + else + { + hPHA->pha_ipd_chanswitch = 0; + } + hPHA->pha_ipd_chan2rephase = 1; + } + hPHA->pha_ipd_chan_cnt = hPHA->pha_ipd_chan_thresh; + } + } + else + { + hPHA->pha_ipd_previouschan2rephase = 1; + hPHA->pha_ipd_chan_cnt = 1; + hPHA->pha_ipd_chanswitch = 0; + } + } + + if ( !hPHA->pha_ipd_chanswitch ) + { + if ( hPHA->pha_ipd_chan2rephase == 0 ) + { + hPHA->p_curr_taps[1] = NULL; + hPHA->p_curr_taps[0] = hPHA->curr_taps[0]; + p_curr_taps = hPHA->p_curr_taps[0]; + p_curr_taps[0] = rfft_pha_buf[0]; + for ( i = 1, j = input_frame_pha - 1; i < hPHA->pha_len; i++, j-- ) + { + p_curr_taps[i] = rfft_pha_buf[j]; + } + } + else + { + hPHA->p_curr_taps[0] = NULL; + hPHA->p_curr_taps[1] = hPHA->curr_taps[1]; + mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len ); + } + } + } + + if ( hPHA->pha_ipd_chanswitch ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + hPHA->p_curr_taps[n] = NULL; + } + } + else if ( hPHA->proc_pha == STEREO_DMX_EVS_PHA_IPD2 ) + { + /* IPDn */ + + set_f( &( Pr[freq_ipd_max] ), 1.0f, ( nsbd - freq_ipd_max ) ); + set_f( &( Pi[freq_ipd_max] ), 0.0f, ( nsbd - freq_ipd_max ) ); + + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + hPHA->p_curr_taps[n] = hPHA->curr_taps[n]; + } + + rfft_pha_buf[0] = 1.; + rfft_pha_buf[1] = 1.; + + ild_cnt = 0; + isd_rate = (float) isd_cnt_l / freq_8k; + for ( i = 1; i < nsbd; i++ ) + { +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + Pr[i] ) / 2.0f ); + rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] ); + if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD ) + { + rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] ); + rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f ); + } +#else + rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + Pr[i] ) / 2.0f ); + rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] ); + if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD ) + { + rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] ); + rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f ); + } +#endif + if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) ) + { + ild_cnt++; + tEr[i] = 1; + } + else + { + tEr[i] = -1; + } + } + if ( ild_cnt > nsbd * STEREO_DMX_EVS_ILD_PRC ) + { + for ( i = 1; i < nsbd; i++ ) + { + if ( tEr[i] > 0 ) + { + rfft_pha_buf[i * 2] = 1.; + rfft_pha_buf[i * 2 + 1] = 0.; + } + } + } + + rfft( rfft_pha_buf, hPHA->rfft_ipd_coef, input_frame_pha, +1 ); + mvr2r( rfft_pha_buf, hPHA->p_curr_taps[1], hPHA->pha_len ); + + /* PHA L2R */ + p_curr_taps = hPHA->p_curr_taps[0]; + p_curr_taps[0] = rfft_pha_buf[0]; + for ( i = 1; i < hPHA->pha_len; i++ ) + { + p_curr_taps[i] = rfft_pha_buf[input_frame_pha - i]; + } + } +#else if ( hPHA->curr_pha == STEREO_DMX_EVS_PHA_IPD ) { hPHA->p_curr_taps[0] = NULL; @@ -592,6 +901,15 @@ static void calc_poc( isd_rate = (float) isd_cnt_l / freq_8k; for ( i = 1; i < nsbd; i++ ) { +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + Pr[i] ) / 2.0f ); + rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] ); + if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD ) + { + rfft_pha_buf[i * 2 + 1] = sqrtf( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] ); + rfft_pha_buf[i * 2] = sqrtf( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f ); + } +#else rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + Pr[i] ) / 2.0f ); rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - Pr[i] ) / 2.0f ) * sign( Pi[i] ); if ( isd_rate > STEREO_DMX_EVS_ISD_DIST_THRES_IPD ) @@ -599,7 +917,7 @@ static void calc_poc( rfft_pha_buf[i * 2 + 1] = (float) sqrt( ( 1.0f - rfft_pha_buf[i * 2] ) / 2.0f ) * sign( rfft_pha_buf[i * 2 + 1] ); rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f ); } - +#endif if ( ( tEr[i] > STEREO_DMX_EVS_LR_EGY * tEl[i] ) || ( tEl[i] > STEREO_DMX_EVS_LR_EGY * tEr[i] ) ) { ild_cnt++; @@ -641,6 +959,7 @@ static void calc_poc( } } } +#endif for ( n = 0; n < CPE_CHANNELS; n++ ) { @@ -656,7 +975,11 @@ static void calc_poc( { energy += hPHA->p_curr_taps[n][i] * hPHA->p_curr_taps[n][i]; } +#ifdef NONBE_FIX_567_DOUBLE_STEREO_DMX + energy = inv_sqrtf( energy + EPSILON ); +#else energy = (float) inv_sqrt( energy + EPSILON ); +#endif for ( i = 0; i < hPHA->pha_len; i++ ) { hPHA->p_curr_taps[n][i] *= energy; @@ -949,10 +1272,12 @@ static void weighted_ave( const float wnd[] /* i : window coef */ ) { +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_POC + int16_t i, len; float gain_tmp = 0.f, gain_sub; - len = input_frame >> 4; + len = input_frame >> 1; gain_sub = gain - old_gain; for ( i = 0; i < len; i++ ) @@ -965,9 +1290,58 @@ static void weighted_ave( dst[i] = src1[i] * gain + src2[i] * ( 1.0f - gain_tmp ); } +#else + int16_t i, len; + float gain_tmp = 0.f, gain_sub; + + len = input_frame >> 4; + gain_sub = gain - old_gain; + + for ( i = 0; i < len; i++ ) + { + gain_tmp = old_gain + gain_sub * wnd[i]; + dst[i] = src1[i] * gain_tmp + src2[i] * ( 1.0f - gain_tmp ); + } + for ( ; i < input_frame; i++ ) + { + dst[i] = src1[i] * gain + src2[i] * ( 1.0f - gain_tmp ); + } +#endif return; } +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA +/*-------------------------------------------------------------------* + * spectral_flatness() + * + * computes spectral flatness SF + * SF(x) = exp(mean_i(ln(x_i))) / mean_i(x_i) + *-------------------------------------------------------------------*/ + +static float spectral_flatness( + const float sig[], /* i : input signal */ + const int16_t sigLength /* i : input signal length */ +) +{ + float geoMean = 0.0f; + float ariMean = 0.0f; + float eps = 1e-10f; + int16_t i; + + /* Initialization */ + for ( i = 0; i < sigLength; i++ ) + { + ariMean += fabsf( sig[i] ) + eps; + geoMean += logf( fabsf( sig[i] ) + eps ); + } + ariMean /= sigLength; + geoMean /= sigLength; + geoMean = expf( geoMean ); + + return geoMean / ariMean; +} + +#endif /*-------------------------------------------------------------------* * calc_energy() @@ -1015,6 +1389,25 @@ static void calc_energy( } +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA +/*-------------------------------------------------------------------* + * calc_energy_sgc() + * + * calculate energy for switch gain control + *-------------------------------------------------------------------*/ +static void calc_energy_sgc( + const float src[], /* i : input signal */ + float *energy, /* o : calculated energy */ + const int16_t input_frame, /* i : input frame length */ + const float ratio /* i : adapting ratio */ +) +{ + *energy = ratio * *energy + ( 1.0f - ratio ) * sum2_f( src, input_frame ); + return; +} +#endif + + /*-------------------------------------------------------------------* * adapt_gain() * @@ -1030,10 +1423,12 @@ static void adapt_gain( const float wnd[] /* i : window coef */ ) { +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_POC + int16_t i, len; float gain_tmp, gain_sub; - len = input_frame >> 4; + len = input_frame >> 1; gain_sub = gain - old_gain; for ( i = 0; i < len; i++ ) @@ -1045,7 +1440,23 @@ static void adapt_gain( { dst[i] = src[i] * gain; } +#else + int16_t i, len; + float gain_tmp, gain_sub; + len = input_frame >> 4; + gain_sub = gain - old_gain; + + for ( i = 0; i < len; i++ ) + { + gain_tmp = old_gain + gain_sub * wnd[i]; + dst[i] = src[i] * gain_tmp; + } + for ( ; i < input_frame; i++ ) + { + dst[i] = src[i] * gain; + } +#endif return; } @@ -1106,6 +1517,48 @@ static void create_M_signal( } +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + +/*-------------------------------------------------------------------* + * apply_gain_sgc() + * + * Apply gain for switching + *-------------------------------------------------------------------*/ + +static void apply_gain_sgc( + float data[], /* i/o : input signal */ + float *gain, /* i : gain */ + float ratio, /* i : ratio */ + const int16_t input_frame /* i : input frame length */ +) +{ + int16_t n; + float lr; + + if ( *gain > STEREO_DMX_EVS_SGC_GH ) + { + lr = 1.0f / ratio; + } + else if ( *gain < STEREO_DMX_EVS_SGC_GL ) + { + lr = ratio; + } + else + { + return; + } + + for ( n = 0; n < input_frame; n++ ) + { + data[n] *= *gain; + } + + *gain *= lr; +} + +#endif + + /*-------------------------------------------------------------------* * stereo_dmx_evs_enc() * @@ -1120,6 +1573,293 @@ void stereo_dmx_evs_enc( const bool is_binaural /* i : indication that input is binaural audio */ ) { +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + + float dmx_weight, corr; + int16_t k, m, n, pha_len, fad_len, input_subframe, input_frame, n_fad_r, n_fad_g, m_fad_g, n_fad_cnt; + float data_f[CPE_CHANNELS][L_FRAME48k]; + float mem_prev[STEREO_DMX_EVS_FAD_LEN_MAX], data_mem[STEREO_DMX_EVS_DATA_LEN_MAX]; + float dmx_poc_data[L_FRAME48k], dmx_pha_data[L_FRAME48k], subframe_energy[STEREO_DMX_EVS_NB_SBFRM]; + float *p_data_mem, *p_prev_taps, *p_curr_taps, *p_data, *p_sub_frame; + float ftmp, *fad_g, *p_dmx_data, *p_dmx_data_fo; + bool is_transient; + STEREO_DMX_EVS_PRC prev_prc; + STEREO_DMX_EVS_PHA_HANDLE hPHA; + + if ( is_binaural ) + { + /* use of is_binaural flag is to be considered */ + } + + input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); + hPHA = hStereoDmxEVS->hPHA; + + for ( n = 0; n < input_frame; n++ ) + { + data_f[0][n] = (float) data[2 * n]; + data_f[1][n] = (float) data[2 * n + 1]; + } + if ( n_samples < input_frame ) + { + set_f( data_f[0] + n_samples, 0.0f, input_frame - n_samples ); + set_f( data_f[1] + n_samples, 0.0f, input_frame - n_samples ); + } + + input_subframe = n_samples / STEREO_DMX_EVS_NB_SBFRM; + is_transient = false; + for ( k = 0; k < CPE_CHANNELS; k++ ) + { + for ( m = 0; m < STEREO_DMX_EVS_NB_SBFRM; m++ ) + { + p_sub_frame = &( data_f[k][m * input_subframe] ); + subframe_energy[m] = sum2_f( p_sub_frame, input_subframe ); + if ( subframe_energy[m] > hPHA->crst_fctr * ( hPHA->trns_aux_energy[k] + EPSILON ) ) + { + is_transient = true; + } + + hPHA->trns_aux_energy[k] = STEREO_DMX_EVS_TRNS_EGY_FORGETTING * hPHA->trns_aux_energy[k] + ( 1.0f - STEREO_DMX_EVS_TRNS_EGY_FORGETTING ) * subframe_energy[m]; + } + + for ( m = 1; m < STEREO_DMX_EVS_NB_SBFRM; m++ ) + { + if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST ) + { + is_transient = true; + } + } + } + + estimate_itd( &corr, hStereoDmxEVS->hPOC, hPHA, data_f[0], data_f[1], &hStereoDmxEVS->itd, input_frame ); + + /* poc */ + + if ( hStereoDmxEVS->itd ) + { + dmx_weight = ( ( hStereoDmxEVS->itd > 0 ) ? ( -1 ) : 1 ) * 0.5f * corr + 0.5f; + } + else + { + dmx_weight = 0.5f; + } + + create_M_signal( data_f[0], data_f[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd, + hStereoDmxEVS->dmx_weight, hStereoDmxEVS->pre_dmx_energy, hStereoDmxEVS->aux_dmx_energy ); + + /* pha */ + + pha_len = hPHA->pha_len; + fad_len = hPHA->fad_len; + fad_g = hPHA->fad_g; + + set_zero( dmx_pha_data, n_samples ); + set_zero( mem_prev, fad_len ); + + for ( k = 0; k < CPE_CHANNELS; k++ ) + { + p_data = data_f[k]; + mvr2r( hPHA->data_mem[k], data_mem, pha_len ); + mvr2r( &( p_data[n_samples - pha_len] ), hPHA->data_mem[k], pha_len ); + p_data_mem = &( data_mem[pha_len] ); + mvr2r( p_data, p_data_mem, n_samples ); + + p_prev_taps = hPHA->p_prev_taps[k]; + if ( p_prev_taps ) + { + for ( n = 0; n < fad_len; n++ ) + { + for ( ftmp = 0, m = 0; m < pha_len; m++ ) + { + ftmp += p_data_mem[n - m] * p_prev_taps[m]; + } + mem_prev[n] += ftmp * INV_SQRT_2; + } + } + else + { + for ( n = 0; n < fad_len; n++ ) + { + mem_prev[n] += p_data[n] * INV_SQRT_2; + } + } + + p_curr_taps = hPHA->p_curr_taps[k]; + if ( p_curr_taps ) + { + for ( n = 0; n < n_samples; n++ ) + { + for ( ftmp = 0, m = 0; m < pha_len; m++ ) + { + ftmp += p_data_mem[n - m] * p_curr_taps[m]; + } + dmx_pha_data[n] += ftmp * INV_SQRT_2; + } + } + else + { + for ( n = 0; n < n_samples; n++ ) + { + dmx_pha_data[n] += p_data[n] * INV_SQRT_2; + } + } + } + + for ( n = 0, m = ( fad_len - 1 ); n < fad_len; n++, m-- ) + { + dmx_pha_data[n] *= fad_g[n]; + dmx_pha_data[n] += ( mem_prev[n] ) * fad_g[m]; + } + + /* prc switch */ + + prev_prc = hPHA->curr_prc; + if ( abs( (int16_t) hStereoDmxEVS->itd ) > hPHA->prc_thres ) + { + if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_POC ) + { + if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_POC ) + { + hPHA->prc_hys_cnt += 1; + } + else + { + hPHA->prc_hys_cnt = 0; + } + + if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES ) + { + hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC; + } + } + hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC; + } + else + { + if ( hPHA->curr_prc != STEREO_DMX_EVS_PRC_PHA ) + { + if ( hPHA->prev_prc == STEREO_DMX_EVS_PRC_PHA ) + { + hPHA->prc_hys_cnt += 1; + } + else + { + hPHA->prc_hys_cnt = 0; + } + + if ( hPHA->prc_hys_cnt >= STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES ) + { + hPHA->curr_prc = STEREO_DMX_EVS_PRC_PHA; + } + } + hPHA->prev_prc = STEREO_DMX_EVS_PRC_PHA; + } + + if ( is_transient || ( hStereoDmxEVS->aux_dmx_energy[0] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[1] ) || ( hStereoDmxEVS->aux_dmx_energy[1] > STEREO_DMX_EVS_ILDS_EGY * hStereoDmxEVS->aux_dmx_energy[0] ) || ( hPHA->force_poc ) ) + { + hPHA->curr_prc = STEREO_DMX_EVS_PRC_POC; + hPHA->prc_hys_cnt = 0; + } + + calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + + if ( ( prev_prc != hPHA->curr_prc ) && !is_transient && !( ( hPHA->dmx_pha_ener < hPHA->low_egy_thres_sgc ) && ( hPHA->dmx_poc_ener < hPHA->low_egy_thres_sgc ) ) ) + { + if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC ) + { + apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + + hPHA->dmx_poc_gain_sgc = sqrtf( hPHA->dmx_pha_ener_sgc / ( hPHA->dmx_poc_ener + EPSILON ) ); + hPHA->dmx_poc_gain_sgc = min( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMAX ); + hPHA->dmx_poc_gain_sgc = max( hPHA->dmx_poc_gain_sgc, STEREO_DMX_EVS_SGC_GMIN ); + + apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + } + else + { + apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + + hPHA->dmx_pha_gain_sgc = sqrtf( hPHA->dmx_poc_ener_sgc / ( hPHA->dmx_pha_ener + EPSILON ) ); + hPHA->dmx_pha_gain_sgc = min( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMAX ); + hPHA->dmx_pha_gain_sgc = max( hPHA->dmx_pha_gain_sgc, STEREO_DMX_EVS_SGC_GMIN ); + + apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + } + } + else + { + apply_gain_sgc( dmx_poc_data, &( hPHA->dmx_poc_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_poc_data, &( hPHA->dmx_poc_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + + apply_gain_sgc( dmx_pha_data, &( hPHA->dmx_pha_gain_sgc ), STEREO_DMX_EVS_SGC_GR_S, n_samples ); + calc_energy_sgc( dmx_pha_data, &( hPHA->dmx_pha_ener_sgc ), n_samples, STEREO_DMX_EVS_SGC_EGY_FORGETTING ); + } + + if ( hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC ) + { + p_dmx_data = dmx_poc_data; + p_dmx_data_fo = dmx_pha_data; + } + else + { + p_dmx_data = dmx_pha_data; + p_dmx_data_fo = dmx_poc_data; + } + + n_fad_r = is_transient ? 1 : STEREO_DMX_EVS_FAD_R; + + if ( prev_prc != hPHA->curr_prc ) + { + if ( hPHA->n_fad_g == input_frame ) + { + hPHA->n_fad_g = 0; + hPHA->n_fad_cnt = 0; + } + else + { + hPHA->n_fad_g = input_frame - hPHA->n_fad_g - 1; + hPHA->n_fad_cnt = is_transient ? 0 : n_fad_r - hPHA->n_fad_cnt; + } + } + else if ( is_transient ) + { + hPHA->n_fad_cnt = 0; + } + + fad_len = min( n_samples, ( ( input_frame * n_fad_r ) - ( hPHA->n_fad_g * n_fad_r + hPHA->n_fad_cnt ) ) ); + + if ( fad_len != 0 ) + { + fad_g = hPHA->fad_g_prc; + n_fad_g = hPHA->n_fad_g; + n_fad_cnt = hPHA->n_fad_cnt; + m_fad_g = input_frame - n_fad_g - 1; + + for ( n = 0; n < fad_len; n++ ) + { + p_dmx_data[n] *= fad_g[n_fad_g]; + p_dmx_data[n] += fad_g[m_fad_g] * p_dmx_data_fo[n]; + + if ( ++n_fad_cnt == n_fad_r ) + { + n_fad_cnt = 0; + n_fad_g++; + m_fad_g--; + } + } + + hPHA->n_fad_g = n_fad_g; + hPHA->n_fad_cnt = n_fad_cnt; + } + + mvr2s( p_dmx_data, data, n_samples ); + +#else + int16_t n; float dmx_weight, corr; float data_f[CPE_CHANNELS][L_FRAME48k]; @@ -1358,6 +2098,7 @@ void stereo_dmx_evs_enc( mvr2s( p_dmx_data, data, n_samples ); +#endif return; } @@ -1378,7 +2119,11 @@ ivas_error stereo_dmx_evs_init_encoder( int16_t n, input_frame; int16_t m, len, pha_len, fad_len, fad_len2, trans_len, itrh, rfft_ipd_coef_step, n0, input_frame_pha; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + float *win, *fad_g, fad_r, tmp_r, a_step, *ipd_ff; +#else float *win, *fad_g, fad_r, tmp_r, a_min, a_max, a_step, *ipd_ff; +#endif const float *p_ipd_w; input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); @@ -1423,7 +2168,12 @@ ivas_error stereo_dmx_evs_init_encoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for STEREO_DMX_EVS_POC_DATA\n" ) ); } +#ifdef BE_FIX_567_DOUBLE_STEREO_DMX + hStereoDmxEVS->hPOC->shift_limit = NS2SA( input_Fs, STEREO_DMX_EVS_SHIFT_LIMIT ); +#else hStereoDmxEVS->hPOC->shift_limit = (int16_t) ( STEREO_DMX_EVS_SHIFT_LIMIT * input_Fs / 1000 ); +#endif + for ( n = 0; n < CPE_CHANNELS; n++ ) { hStereoDmxEVS->hPOC->peakQ[n] = 0.0f; @@ -1491,6 +2241,9 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_16; hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_16; hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_16; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_16; +#endif } else if ( input_Fs == 32000 ) { @@ -1498,6 +2251,9 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_32; hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_32; hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_32; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_32; +#endif } else if ( input_Fs == 48000 ) { @@ -1505,6 +2261,9 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->fad_len = STEREO_DMX_EVS_FAD_LEN_48; hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_48; hStereoDmxEVS->hPHA->crst_fctr = STEREO_DMX_EVS_CRST_FCTR_48; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + hStereoDmxEVS->hPHA->low_egy_thres_sgc = STEREO_DMX_EVS_SGC_LEGY_THRES_48; +#endif } else { @@ -1512,7 +2271,9 @@ ivas_error stereo_dmx_evs_init_encoder( } hStereoDmxEVS->hPHA->pha_len = len / 2; +#ifndef NONBE_FIX_947_STEREO_DMX_EVS_PHA hStereoDmxEVS->hPHA->init_frmCntr = (int16_t) ( FRAMES_PER_SEC * 0.2f ); +#endif hStereoDmxEVS->hPHA->isd_rate_s = 0.0f; hStereoDmxEVS->hPHA->iccr_s = 0.0f; @@ -1520,13 +2281,21 @@ ivas_error stereo_dmx_evs_init_encoder( fad_len = hStereoDmxEVS->hPHA->fad_len; trans_len = (int16_t) ( (float) pha_len / 20.0f ); +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + set_f( hStereoDmxEVS->hPHA->win, STEREO_DMX_EVS_PHA_WND_C, pha_len - trans_len ); +#else set_f( hStereoDmxEVS->hPHA->win, 1.8f, pha_len - trans_len ); +#endif hStereoDmxEVS->hPHA->win[0] = 1.0f; tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 ); win = &( hStereoDmxEVS->hPHA->win[pha_len - trans_len] ); for ( n = 0; n < trans_len; n++ ) { +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * STEREO_DMX_EVS_PHA_WND_C; +#else win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * 1.8f; +#endif } fad_g = hStereoDmxEVS->hPHA->fad_g; @@ -1542,6 +2311,37 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->prev_pha = STEREO_DMX_EVS_PHA_IPD; hStereoDmxEVS->hPHA->pha_hys_cnt = 0; +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + hStereoDmxEVS->hPHA->pha_ipd_chan_cnt = 0; + hStereoDmxEVS->hPHA->pha_ipd_chan_thresh = 10; + hStereoDmxEVS->hPHA->pha_ipd_ild_thresh = STEREO_DMX_EVS_IPD_ILD_THRES; + hStereoDmxEVS->hPHA->pha_ipd_chan2rephase = 1; + hStereoDmxEVS->hPHA->pha_ipd_previouschan2rephase = 1; + hStereoDmxEVS->hPHA->pha_ipd_chanswitch = 0; + hStereoDmxEVS->hPHA->pha_ipd_chanswitch_allowed = 0; + hStereoDmxEVS->hPHA->pha_ipd_sf_Threshold = STEREO_DMX_EVS_IPD_SF_THRES; + + hStereoDmxEVS->hPHA->proc_pha = STEREO_DMX_EVS_PHA_IPD; + hStereoDmxEVS->hPHA->force_poc = FALSE; + + /* Compute the forgetting factor */ + itrh = (int16_t) ( ( STEREO_DMX_EVS_IFF_FREQ * input_frame ) / ( input_Fs * STEREO_DMX_EVS_SUBBAND_SIZE ) ); + n0 = L_FRAME16k / ( 2 * STEREO_DMX_EVS_SUBBAND_SIZE ); + a_step = ( STEREO_DMX_EVS_IFF_AMIN - STEREO_DMX_EVS_IFF_AMAX ) / ( n0 + 1 - itrh ); + ipd_ff = hStereoDmxEVS->hPHA->ipd_ff; + for ( n = 0; n < itrh; n++ ) + { + ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX; + } + for ( ; n < ( n0 + 1 ); n++ ) /* 8kHz */ + { + ipd_ff[n] = STEREO_DMX_EVS_IFF_AMAX + ( n - itrh ) * a_step; + } + for ( ; n < STEREO_DMX_EVS_NB_SUBBAND_MAX; n++ ) + { + ipd_ff[n] = STEREO_DMX_EVS_IFF_AMIN; + } +#else /* Compute the forgetting factor */ a_min = 0.8576958985908941f; a_max = 0.9440608762859234f; @@ -1561,6 +2361,7 @@ ivas_error stereo_dmx_evs_init_encoder( { ipd_ff[n] = a_min; } +#endif set_f( hStereoDmxEVS->hPHA->Pr, 1.0, STEREO_DMX_EVS_NB_SUBBAND_MAX ); set_zero( hStereoDmxEVS->hPHA->Pi, STEREO_DMX_EVS_NB_SUBBAND_MAX ); @@ -1600,8 +2401,10 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->prev_prc = STEREO_DMX_EVS_PRC_POC; hStereoDmxEVS->hPHA->prc_hys_cnt = 0; +#ifndef NONBE_FIX_947_STEREO_DMX_EVS_PHA hStereoDmxEVS->hPHA->fad_len_prc = (int16_t) ( STEREO_DMX_EVS_FADE_LEN_PRC * (float) input_Fs / 1000.0f ); - fad_len = hStereoDmxEVS->hPHA->fad_len_prc; +#endif + fad_len = input_frame; fad_g = hStereoDmxEVS->hPHA->fad_g_prc; fad_r = 1.0f / (float) ( fad_len + 1 ); fad_len2 = fad_len / 2; @@ -1616,6 +2419,21 @@ ivas_error stereo_dmx_evs_init_encoder( hStereoDmxEVS->hPHA->trns_aux_energy[n] = 0.0f; } +#ifdef NONBE_FIX_947_STEREO_DMX_EVS_PHA + + hStereoDmxEVS->hPHA->n_fad_g = input_frame; + hStereoDmxEVS->hPHA->n_fad_cnt = 0; + + hStereoDmxEVS->hPHA->dmx_pha_ener_sgc = 0.0f; + hStereoDmxEVS->hPHA->dmx_poc_ener_sgc = 0.0f; + hStereoDmxEVS->hPHA->dmx_pha_gain_sgc = 1.0f; + hStereoDmxEVS->hPHA->dmx_poc_gain_sgc = 1.0f; + + hStereoDmxEVS->hPHA->dmx_pha_ener = 0.0f; + hStereoDmxEVS->hPHA->dmx_poc_ener = 0.0f; + +#endif + *hStereoDmxEVS_out = hStereoDmxEVS; return IVAS_ERR_OK;