diff --git a/lib_com/options.h b/lib_com/options.h index 8a35f4f6f43c91477f71e36fa50b8837baa11669..d62cb1880b1ed327b96d3f6f32b3afc6e2a12841 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -173,6 +173,8 @@ #define FIX_ISM_METADATA_READER /* Issue 211: make ISM metadata file reader robust against invalid files */ #define FIX_GET_DELAY_RETURN /* Issue 223: change return data type in function get_delay() */ +/* NTT switches */ +#define NTT_REDUC_COMP_POC /* Contribution : Complexity reduction of phase spectrum in stereo downmix*/ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index a6773bc64c7408737920af691d03a3cc51bd87e1..b0ec2f1c8ed0f22c5b6085ca389a48a288cfa833 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -155,11 +155,23 @@ static void calc_poc( const float *s; float *P; float tmp1, tmp2, Lr, Li, Rr, Ri, gamma, igamma, iN; + +#ifdef NTT_REDUC_COMP_POC + float specPOr[L_FRAME48k / 2 + 1], specPOi[L_FRAME48k / 2]; /*real and imaginary values for searching phase angle*/ + float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k]; + float rfft_buf[L_FRAME48k]; + int16_t step, bias; + int16_t mult_angle; + int16_t j; + int16_t end; +#else float specPOr[L_FRAME48k], specPOi[L_FRAME48k]; float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k]; float rfft_buf[L_FRAME48k]; int16_t step, bias; int16_t i_for; +#endif + int16_t cos_step, cos_max; float eps_cos, eps_sin, EPS; @@ -170,9 +182,171 @@ static void calc_poc( P = hPOC->P; n0 = input_frame / 2; itdLR = hPOC->itdLR; + igamma = STEREO_DMX_EVS_POC_GAMMA * iN; gamma = 1.0f - igamma; +#ifdef NTT_REDUC_COMP_POC /*apploximation of phase angle on an unit circle without using sqrt()*/ + + step = 1; + bias = 0; + cos_step = 2; + cos_max = n0; + mult_angle = 3; + + if ( input_frame == L_FRAME16k ) + { + step = 3; + bias = 1; + cos_step = 4; + cos_max = input_frame; + mult_angle = 2; /*****/ + } + if ( input_frame == L_FRAME32k ) + { + mult_angle = 2; + } + + end = min( n0, 320 ); + specPOr[0] = sign( specLr[0] * specRr[0] ) * wnd[bias]; + specPOi[0] = 0.0f; + EPS = hPOC->eps; + if ( input_frame == L_FRAME48k ) + { + for ( i = 1; i < n0 / 2; i++ ) + { + eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS; + eps_sin = s[i * cos_step /*i_for*/] * EPS; + Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin; + Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos; + Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin; + Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos; + + specPOr[i] = ( Lr * Rr + Li * Ri ); + specPOi[i] = ( Lr * Ri - Li * Rr ); + j = n0 - i; + if ( j < 320 ) + { + Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin; + Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos; + Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin; + Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos; + + specPOr[j] = ( Lr * Rr + Li * Ri ); + specPOi[j] = ( Lr * Ri - Li * Rr ); + } + } + } + else /* 16kHz and 32 kHz*/ + { + for ( i = 1; i < n0 / 2; i++ ) + { + eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS; + eps_sin = s[i * cos_step /*i_for*/] * EPS; + + Lr = specLr[i] + specRr[i] * eps_cos + specRi[i] * eps_sin; + Li = specLi[i] - specRr[i] * eps_sin + specRi[i] * eps_cos; + Rr = specRr[i] + specLr[i] * eps_cos + specLi[i] * eps_sin; + Ri = specRi[i] - specLr[i] * eps_sin + specLi[i] * eps_cos; + specPOr[i] = ( Lr * Rr + Li * Ri ); + specPOi[i] = ( Lr * Ri - Li * Rr ); + + j = n0 - i; + Lr = specLr[j] - specRr[j] * eps_cos + specRi[j] * eps_sin; + Li = specLi[j] - specRr[j] * eps_sin - specRi[j] * eps_cos; + Rr = specRr[j] - specLr[j] * eps_cos + specLi[j] * eps_sin; + Ri = specRi[j] - specLr[j] * eps_sin - specLi[j] * eps_cos; + specPOr[j] = ( Lr * Rr + Li * Ri ); + specPOi[j] = ( Lr * Ri - Li * Rr ); + } + } + { + /* i=n0/2*/ + Lr = specLr[i] + specRi[i] * EPS; + Li = specLi[i] - specRr[i] * EPS; + Rr = specRr[i] + specLi[i] * EPS; + Ri = specRi[i] - specLr[i] * EPS; + specPOr[i] = ( Lr * Rr + Li * Ri ); + specPOi[i] = ( Lr * Ri - Li * Rr ); + } + /* complex spectrum (specPOr[i], specPOi[i]) are placed on an unit circle without using srqt()*/ + for ( i = 1; i < 10; i++ ) /*search from 4 angles */ + { + tmp1 = wnd[i * step + bias] * gamma; + + specPOr[i] = sign( specPOr[i] ) * 0.866f * tmp1; /* low angles are more frequent for low frequency */ + specPOi[i] = sign( specPOi[i] ) * 0.5f * tmp1; + gamma -= igamma; + } + for ( ; i < n0 >> 4; i++ ) /*search from 4 angles */ + { + tmp1 = wnd[i * step + bias] * gamma * 0.7071f; + + specPOr[i] = sign( specPOr[i] ) * tmp1; + specPOi[i] = sign( specPOi[i] ) * tmp1; /* low accuracy is adequate for low frequency */ + gamma -= igamma; + } + + for ( ; i < n0 >> 3; i++ ) /* binary search from 8 angles */ + { + tmp1 = wnd[i * step + bias] * gamma; + + if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 ) + { + specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle]; /* cos(PI/8)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle]; + } + else + { + specPOr[i] = sign( specPOr[i] ) * tmp1 * /*0.382683f*/ s[40 * mult_angle]; /* cos(PI*3/8)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 * /*0.923880f*/ s[120 * mult_angle]; + } + gamma -= igamma; + } + for ( ; i < end; i++ ) /* binary search from 16 angles */ + { + tmp1 = wnd[i * step + bias] * gamma; + if ( ( specPOr[i] - specPOi[i] ) * ( specPOr[i] + specPOi[i] ) > 0 ) + { + if ( ( specPOr[i] * 0.414213f - specPOi[i] ) * ( specPOr[i] * 0.414213f + specPOi[i] ) > 0 ) /*tan(PI/8)*/ + { + specPOr[i] = sign( specPOr[i] ) * tmp1 /*0.980785f */ * s[140 * mult_angle]; /* cos(PI/16)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 /*0.195090f */ * s[20 * mult_angle]; + } + else + { + specPOr[i] = sign( specPOr[i] ) * tmp1 /* 0.831470f */ * s[100 * mult_angle]; /*cos(PI*3/16)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 /* 0.555570f*/ * s[60 * mult_angle]; + } + } + else + { + if ( ( specPOr[i] - specPOi[i] * 0.414213f ) * ( specPOr[i] + specPOi[i] * 0.414213f ) > 0 ) /*tan(PI/8)*/ + { + specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.555570f*/ * s[60 * mult_angle]; /*cos(PI*5/16)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.831470f*/ * s[100 * mult_angle]; + } + else + { + specPOr[i] = sign( specPOr[i] ) * tmp1 /** 0.195090f*/ * s[20 * mult_angle]; /*cos(PI*7/16)*/ + specPOi[i] = sign( specPOi[i] ) * tmp1 /** 0.980785f*/ * s[140 * mult_angle]; + } + } + gamma -= igamma; + } + + if ( i < n0 ) + { + gamma -= igamma * ( n0 - 320 ); + } + for ( ; i < n0; i++ ) /*neglect higher frequency bins when 48 kHz samplng*/ + { + specPOr[i] = 0.f; + specPOi[i] = 0.f; + } + specPOr[n0] = sign( specLr[n0] * specRr[n0] ) * wnd[i * step + bias] * gamma; + +#else /*NTT_REDUC_COMP_POC*/ if ( input_frame == L_FRAME16k ) { step = 3; @@ -199,7 +373,6 @@ static void calc_poc( cos_step = 2; cos_max = n0; } - for ( i = 1; i < n0 / 2; i++ ) { Lr = specLr[i]; @@ -213,6 +386,7 @@ static void calc_poc( Li += ( -specRr[i] * eps_sin + specRi[i] * eps_cos ); Rr += ( specLr[i] * eps_cos + specLi[i] * eps_sin ); Ri += ( -specLr[i] * eps_sin + specLi[i] * eps_cos ); + tmp1 = wnd[i * step + bias] * gamma / ( sqrtf( ( ( Lr * Lr + Li * Li ) ) * ( ( Rr * Rr + Ri * Ri ) ) ) + EPS ); specPOr[i] = ( Lr * Rr + Li * Ri ) * tmp1; @@ -245,6 +419,7 @@ static void calc_poc( } specPOr[n0] = sign( specLr[i] ) * sign( specRr[i] ) * wnd[i * step + bias] * gamma; +#endif rfft_buf[0] = specPOr[0]; rfft_buf[1] = specPOr[n0];