Commit 1f59b328 authored by sekine's avatar sekine
Browse files

Additional reduction of WMOPS for NTT_REDUC_COMP_POC.

parent 9786a7a7
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -150,8 +150,6 @@
#define SPAR_SCALING_HARMONIZATION                      /* Issue 80: Changes to harmonize scaling in spar */
#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*/

+176 −211
Original line number Diff line number Diff line
@@ -160,14 +160,23 @@ static void calc_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;

    int16_t index_angles, mult_angle;

    bool diffIR;
    const float *cos_reverse;

    float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k];
    float rfft_buf[L_FRAME48k];
    int16_t step, bias;
#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;
    int16_t i_for;
#endif

    int16_t cos_step, cos_max;
    float eps_cos, eps_sin, EPS;

@@ -181,50 +190,79 @@ static void calc_poc(
    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()*/
    if ( input_frame == L_FRAME16k )
    {
        step = 3;
        bias = 1;
        cos_step = 4;
        cos_max = input_frame;
        mult_angle = 1;
    }
    else
    {
        step = 1;
        bias = 0;
        cos_step = 2;
        cos_max = n0;
        mult_angle = 2;
        if ( input_frame == L_FRAME48k )
            mult_angle = 3;
    }
    cos_reverse = s + cos_max;

    specPOr[0] = sign( specLr[0] ) * sign( specRr[0] ) * wnd[bias];
    specPOi[0] = 0.0f;

    EPS = hPOC->eps;
    if ( input_frame == L_FRAME48k )
    {
        for ( i = 1; i < n0 / 2; i++ )
        {
            Lr = specLr[i];
            Li = specLi[i];
            Rr = specRr[i];
            Ri = specRi[i];

    if ( input_frame == L_FRAME16k )
            eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
            eps_sin = s[i * cos_step /*i_for*/] * EPS;
            Lr += ( Rr * eps_cos + Ri * eps_sin );
            Li += ( -Rr * eps_sin + Ri * 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;
            if ( j < 320 )
            {
        cos_step = 4;
        cos_max = input_frame;
                Lr = specLr[j];
                Li = specLi[j];
                Rr = specRr[j];
                Ri = specRi[j];
                Lr += ( -Rr * eps_cos + Ri * eps_sin );
                Li += ( -Rr * eps_sin - Ri * 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 );
            }
    else /* for 32 kHz & 48 kHz*/
    {
        cos_step = 2;
        cos_max = n0;
        }

#ifdef NTT_REDUC_COMP_POC
    /*apploximation of phase angle on an unit circle without using sqrt()*/
    }
    else /* 16kHz and 32 kHz*/
    {
        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 );
            eps_cos = s[cos_max - i * cos_step /*cos_max - i_for*/] * EPS;
            eps_sin = s[i * cos_step /*i_for*/] * EPS;
            Lr += ( Rr * eps_cos + Ri * eps_sin );
            Li += ( -Rr * eps_sin + Ri * 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 );

@@ -233,79 +271,74 @@ static void calc_poc(
            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 );
            Lr += ( -Rr * eps_cos + Ri * eps_sin );
            Li += ( -Rr * eps_sin - Ri * 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;
        /* 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;
        tmp1 = wnd[i * step + bias] * gamma;
        gamma -= igamma;

        specPOr[i] = sign( specPOr[i] ) * 0.866f * tmp1; /* low angles are more frequent for low frequency */
        specPOi[i] = sign( specPOi[i] ) * 0.5f * tmp1;
    }
    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;
        tmp1 = wnd[i * step + bias] * gamma * 0.7071f;
        gamma -= igamma;

        specPOr[i] = sign( specPOr[i] ) * tmp1;
        specPOi[i] = sign( specPOi[i] ) * tmp1; /* low accuracy is adequate for low frequency */
    }
    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

        diffIR = aR > aI;
        index_angles = 120 - (int16_t) diffIR * 80;
        {
            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) */
            tmp1 = wnd[i * step + bias] * gamma;
            gamma -= igamma;
            specPOr[i] = sign( specPOr[i] ) * cos_reverse[-index_angles * mult_angle] * tmp1 /*s[cos_max - index_angles]*/;
            specPOi[i] = sign( specPOi[i] ) * s[index_angles * mult_angle] * tmp1;
        }
    }
    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) */
            diffIR = aR * 0.414213f /*tanf(PI/8)*/ > aI;
            index_angles = 60 - (int16_t) diffIR * 40;
        }
        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 */
            }
            diffIR = aR > aI * 0.41421356f /*tanf(PI/8)*/;
            index_angles = 140 - (int16_t) diffIR * 40;
        }
        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;
            }
            tmp1 = wnd[i * step + bias] * gamma;
            gamma -= igamma;
            specPOr[i] = sign( specPOr[i] ) * cos_reverse[-index_angles * mult_angle] * tmp1 /*s[cos_max - index_angles]*/;
            specPOi[i] = sign( specPOi[i] ) * s[index_angles * mult_angle] * tmp1;
        }
    }

@@ -318,59 +351,33 @@ static void calc_poc(
        {
            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;
                diffIR = aR * 0.19891f /*tanf(PI/16)*/ > aI;
                index_angles = 30 - (int16_t) diffIR * 20;
            }
            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;
                }
                diffIR = aR * 0.66818f /*tanf(PI*3/16)*/ > aI;
                index_angles = 70 - (int16_t) diffIR * 20;
            }
        }
        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;
                diffIR = aR > aI * 0.668179f /*tanf(PI*3/16)*/;
                index_angles = 110 - (int16_t) diffIR * 20;
            }
            else
            {
                    specPOr[i] = sign( specPOr[i] ) * 0.471397f;
                    specPOi[i] = sign( specPOi[i] ) * 0.881921f;
                }
                diffIR = aR > aI * 0.198912f /*tanf(PI/16)*/;
                index_angles = 150 - (int16_t) diffIR * 20;
            }
            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;
                }
            }
            tmp1 = wnd[i * step + bias] * gamma;
            gamma -= igamma;
            specPOr[i] = sign( specPOr[i] ) * cos_reverse[-index_angles * mult_angle] * tmp1 /*s[cos_max - index_angles]*/;
            specPOi[i] = sign( specPOi[i] ) * s[index_angles * mult_angle] * tmp1;
        }
    }

@@ -378,65 +385,32 @@ static void calc_poc(
    {
        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;
                    diffIR = aR * 0.0984914f /*tanf(PI/32)*/ > aI;
                    index_angles = 15 - (int16_t) diffIR * 10;
                }
                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;
                    }
                    diffIR = aR * 0.3033467f /*tanf(PI*3/32)*/ > aI;
                    index_angles = 35 - (int16_t) diffIR * 10;
                }
            }
            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;
                    diffIR = aR * 0.534511f /*tanf(PI*5/32)*/ > aI;
                    index_angles = 55 - (int16_t) diffIR * 10;
                }
                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;
                    }
                    diffIR = aR * 0.8206788f /*tanf(PI*7/32)*/ > aI;
                    index_angles = 75 - (int16_t) diffIR * 10;
                }
            }
        }
@@ -446,68 +420,35 @@ static void calc_poc(
            {
                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;
                    diffIR = aR > aI * 0.820681f /*tanf(PI*7/32)*/;
                    index_angles = 95 - (int16_t) diffIR * 10;
                }
                else
                {
                        specPOr[i] = sign( specPOr[i] ) * 0.427555f;
                        specPOi[i] = sign( specPOi[i] ) * 0.903989f;
                    }
                    diffIR = aR > aI * 0.5345111f /*tanf(PI*5/32)*/;
                    index_angles = 115 - (int16_t) diffIR * 10;
                }
            }
            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;
                    diffIR = aR > aI * 0.3033467f /*tanf(PI*3/32)*/;
                    index_angles = 135 - (int16_t) diffIR * 10;
                }
                else
                {
                        specPOr[i] = sign( specPOr[i] ) * 0.049068f;
                        specPOi[i] = sign( specPOi[i] ) * 0.998795f;
                    diffIR = aR > aI * 0.098491f /*tanf(PI/32)*/;
                    index_angles = 155 - (int16_t) diffIR * 10;
                }
            }
        }
        }
    }
    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;
            specPOr[i] = sign( specPOr[i] ) * cos_reverse[-index_angles * mult_angle] * tmp1 /*s[cos_max - index_angles]*/;
            specPOi[i] = sign( specPOi[i] ) * s[index_angles * mult_angle] * tmp1;
        }
    }
    if ( i < n0 )
    {
@@ -519,9 +460,33 @@ static void calc_poc(
        specPOi[i] = 0.f;
    }
    specPOr[n0] = sign( specLr[n0] ) * sign( specRr[n0] ) * wnd[i * step + bias] * gamma;

#else
    if ( input_frame == L_FRAME16k )
    {
        step = 3;
        bias = 1;
    }
    else
    {
        step = 1;
        bias = 0;
    }

    specPOr[0] = sign( specLr[0] ) * sign( specRr[0] ) * wnd[bias];
    specPOi[0] = 0.0f;

    EPS = hPOC->eps;

    if ( input_frame == L_FRAME16k )
    {
        cos_step = 4;
        cos_max = input_frame;
    }
    else /* for 32 kHz & 48 kHz */
    {
        cos_step = 2;
        cos_max = n0;
    }
    for ( i = 1; i < n0 / 2; i++ )
    {
        Lr = specLr[i];