Commit 9786a7a7 authored by sekine's avatar sekine
Browse files

Reduction of complexity for phase only correlation in stereo downmix for EVS.

parent ccf6ae2f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -151,6 +151,10 @@
#define FIX_I2_BWD                                      /* Issue 2: BWD fix to more quickly react to WB -> SWB/FB change */ 



/* NTT switches */
#define NTT_REDUC_COMP_POC                              /* Contribution  : Complexity reduction of phase spectrum in stereo downmix */

/* ################## End DEVELOPMENT switches ######################### */
/* clang-format on */
#endif
+324 −1
Original line number Diff line number Diff line
@@ -155,7 +155,15 @@ 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 part of spectrum*/
    float aR, aI;                                               /*real and imaginary values for searching phase angle*/
    int16_t j;
#else
    float specPOr[L_FRAME48k], specPOi[L_FRAME48k];
#endif

    float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k];
    float rfft_buf[L_FRAME48k];
    int16_t step, bias;
@@ -200,6 +208,320 @@ static void calc_poc(
        cos_max = n0;
    }

#ifdef NTT_REDUC_COMP_POC
    /*apploximation of phase angle on an unit circle without using sqrt()*/
    for ( i = 1; i < n0 / 2; i++ )
    {
        Lr = specLr[i];
        Li = specLi[i];
        Rr = specRr[i];
        Ri = specRi[i];

        i_for = i * cos_step;
        eps_cos = s[cos_max - i_for] * EPS;
        eps_sin = s[i_for] * EPS;
        Lr += ( specRr[i] * eps_cos + specRi[i] * eps_sin );
        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 );

        specPOr[i] = ( Lr * Rr + Li * Ri );
        specPOi[i] = ( Lr * Ri - Li * Rr );

        j = n0 - i;
        Lr = specLr[j];
        Li = specLi[j];
        Rr = specRr[j];
        Ri = specRi[j];
        Lr += ( -specRr[j] * eps_cos + specRi[j] * eps_sin );
        Li += ( -specRr[j] * eps_sin - specRi[j] * eps_cos );
        Rr += ( -specLr[j] * eps_cos + specLi[j] * eps_sin );
        Ri += ( -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 */
    {
        specPOr[i] = sign( specPOr[i] ) * 0.866f; /* low angles are more frequent for low frequency */
        specPOi[i] = sign( specPOi[i] ) * 0.5f;
    }
    for ( i = 10; i<n0>> 4; i++ ) /*search from 4 angles */
    {
        specPOr[i] = sign( specPOr[i] ) * 0.7071f; /* low accuracy is adequate for low frequency */
        specPOi[i] = sign( specPOi[i] ) * 0.7071f;
    }
    for ( i = n0 >> 4; i<n0>> 3; i++ ) /* binary search from 8 angles */
    {
        aR = fabsf( specPOr[i] );
        aI = fabsf( specPOi[i] );
        if ( aR > aI )
        {
            specPOr[i] = sign( specPOr[i] ) * 0.92388f;  /* (wnd[n0>>2]+wnd[(n0>>2)-1])*0.5f) */
            specPOi[i] = sign( specPOi[i] ) * 0.382683f; /* (wnd[n0>>2]+wnd[(n0>>2)-1])*0.5f) */
        }
        else
        {
            specPOr[i] = sign( specPOr[i] ) * 0.382683f; /* (wnd[n0>>2]+wnd[(n0>>2)-1])*0.5f) */
            specPOi[i] = sign( specPOi[i] ) * 0.92388f;  /* (wnd[(n0>>2)*3]+wnd[((n0>>2)*3)-1])*0.5f) */
        }
    }
    for ( i = n0 >> 3; i<n0>> 2; i++ ) /* binary search from 16 angles */
    {
        aR = fabsf( specPOr[i] );
        aI = fabsf( specPOi[i] );
        if ( aR > aI )
        {
            if ( aR * 0.414213f /*tanf(PI/8)*/ > aI )
            {
                specPOr[i] = sign( specPOr[i] ) * 0.980785f; /* (wnd[(n0>>3)*7]+wnd[((n0>>3)*7)-1])*0.5f */
                specPOi[i] = sign( specPOi[i] ) * 0.19509f;  /* (wnd[n0>>3]+wnd[(n0>>3)-1])*0.5f) */
            }
            else
            {
                specPOr[i] = sign( specPOr[i] ) * 0.83147f; /* (wnd[(n0>>3)*5]+wnd[((n0>>3)*5)-1])*0.5f */
                specPOi[i] = sign( specPOi[i] ) * 0.55557f; /* (wnd[(n0>>3)*3]+wnd[(n0>>3)*3-1])*0.5f */
            }
        }
        else
        {
            if ( aR > aI * 0.41421356f /*tanf(PI/8)*/ )
            {
                specPOr[i] = sign( specPOr[i] ) * 0.55557f;
                specPOi[i] = sign( specPOi[i] ) * 0.83147f;
            }
            else
            {
                specPOr[i] = sign( specPOr[i] ) * 0.19509f;
                specPOi[i] = sign( specPOi[i] ) * 0.980785f;
            }
        }
    }

    for ( i = n0 >> 2; i<n0>> 1; i++ ) /* binary search from 32 angles */
    {
        aR = fabsf( specPOr[i] );
        aI = fabsf( specPOi[i] );

        if ( aR > aI )
        {
            if ( aR * 0.4142136f /*tanf(PI/8)*/ > aI )
            {
                if ( aR * 0.19891f /*tanf(PI/16)*/ > aI )
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.995185f;
                    specPOi[i] = sign( specPOi[i] ) * 0.098017f;
                }
                else
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.95694f;
                    specPOi[i] = sign( specPOi[i] ) * 0.290285f;
                }
            }
            else
            {
                if ( aR * 0.66818f /*tanf(PI*3/16)*/ > aI )
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.881921f;
                    specPOi[i] = sign( specPOi[i] ) * 0.471397f;
                }
                else
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.77301f;
                    specPOi[i] = sign( specPOi[i] ) * 0.634393f;
                }
            }
        }
        else
        {
            if ( aR > aI * 0.4142136f /*tanf(PI/8)*/ )
            {
                if ( aR > aI * 0.668179f /*tanf(PI*3/16)*/ )
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.634393f;
                    specPOi[i] = sign( specPOi[i] ) * 0.77301f;
                }
                else
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.471397f;
                    specPOi[i] = sign( specPOi[i] ) * 0.881921f;
                }
            }
            else
            {
                if ( aR > aI * 0.198912f /*tanf(PI/16)*/ )
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.290285f;
                    specPOi[i] = sign( specPOi[i] ) * 0.95694f;
                }
                else
                {
                    specPOr[i] = sign( specPOr[i] ) * 0.098017f;
                    specPOi[i] = sign( specPOi[i] ) * 0.995158f;
                }
            }
        }
    }

    for ( i = n0 >> 1; i < min( n0, 320 ); i++ ) /* binary search from 64 angles */
    {
        aR = fabsf( specPOr[i] );
        aI = fabsf( specPOi[i] );

        if ( aR > aI )
        {
            if ( aR * 0.414213f /*tanf(PI/8)*/ > aI )
            {
                if ( aR * 0.19891f /*tanf(PI/16)*/ > aI )
                {
                    if ( aR * 0.0984914f /*tanf(PI/32)*/ > aI )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.99879f;
                        specPOi[i] = sign( specPOi[i] ) * 0.04907f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.98918f;
                        specPOi[i] = sign( specPOi[i] ) * 0.14763f;
                    }
                }
                else
                {
                    if ( aR * 0.303347f /*tanf(PI*3/32)*/ > aI )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.970031f;
                        specPOi[i] = sign( specPOi[i] ) * 0.24298f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.941544f;
                        specPOi[i] = sign( specPOi[i] ) * 0.33689f;
                    }
                }
            }
            else
            {
                if ( aR * 0.66818f /*tanf(PI*3/16)*/ > aI )
                {
                    if ( aR * 0.534511f /*tanf(PI*5/32)*/ > aI )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.903989f;
                        specPOi[i] = sign( specPOi[i] ) * 0.427555f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.857729f;
                        specPOi[i] = sign( specPOi[i] ) * 0.514103f;
                    }
                }
                else
                {
                    if ( aR * 0.8206788f /*tanf(PI*7/32)*/ > aI )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.803208f;
                        specPOi[i] = sign( specPOi[i] ) * 0.595699f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.740951f;
                        specPOi[i] = sign( specPOi[i] ) * 0.671559f;
                    }
                }
            }
        }
        else
        {
            if ( aR > aI * 0.4142136f /*tanf(PI/8)*/ )
            {
                if ( aR > aI * 0.6681767f /*tanf(PI*3/16)*/ )
                {
                    if ( aR > aI * 0.820681f /*tanf(PI*7/32)*/ )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.671559f;
                        specPOi[i] = sign( specPOi[i] ) * 0.740951f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.595699f;
                        specPOi[i] = sign( specPOi[i] ) * 0.803208f;
                    }
                }
                else
                {
                    if ( aR > aI * 0.5345111f /*tanf(PI*5/32)*/ )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.514103f;
                        specPOi[i] = sign( specPOi[i] ) * 0.857729f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.427555f;
                        specPOi[i] = sign( specPOi[i] ) * 0.903989f;
                    }
                }
            }
            else
            {
                if ( aR > aI * 0.1989124f /*tanf(PI/16)*/ )
                {
                    if ( aR > aI * 0.3033467f /*tanf(PI*3/32)*/ )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.33689f;
                        specPOi[i] = sign( specPOi[i] ) * 0.941544f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.24298f;
                        specPOi[i] = sign( specPOi[i] ) * 0.970031f;
                    }
                }
                else
                {
                    if ( aR > aI * 0.098491f /*tanf(PI/32)*/ )
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.14673f;
                        specPOi[i] = sign( specPOi[i] ) * 0.989177f;
                    }
                    else
                    {
                        specPOr[i] = sign( specPOr[i] ) * 0.049068f;
                        specPOi[i] = sign( specPOi[i] ) * 0.998795f;
                    }
                }
            }
        }
    }
    for ( i = 1; i < min( n0, 320 ); i++ ) /*neglect highest frequency bins when 48 kHz samplng*/
    {
        tmp1 = wnd[i * step + bias] * gamma;
        specPOr[i] *= tmp1;
        specPOi[i] *= tmp1;
        gamma -= igamma;
    }
    if ( i < n0 )
    {
        gamma -= igamma * ( n0 - 320 );
    }
    for ( /* i = min(n0, 320) */; i < n0; i++ ) /*neglect higher frequency bins when 48 kHz samplng*/
    {
        specPOr[i] = 0.f;
        specPOi[i] = 0.f;
    }
    specPOr[n0] = sign( specLr[n0] ) * sign( specRr[n0] ) * wnd[i * step + bias] * gamma;

#else

    for ( i = 1; i < n0 / 2; i++ )
    {
        Lr = specLr[i];
@@ -245,6 +567,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];