/*====================================================================================
    EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006
  ====================================================================================*/

#include <math.h>
#include "prot.h"


/*-------------------------------------------------------------------*
 * spec_flatness()
 *
 *
 *-------------------------------------------------------------------*/

void spec_flatness(
    float spec_amp[],               /*(i) spectral amplitude*/
    float smooth_spec_amp[],        /*(i) smoothed spectral amplitude*/
    float sSFM[]                    /*(o) spectral flatness rate*/
)
{
    int i;
    double prods,sums;
    float min_sfm,SFM;

    for(i=0; i<SPEC_AMP_NUM; i++)
    {
        smooth_spec_amp[i] = smooth_spec_amp[i]*0.7f + spec_amp[i]*0.3f;
    }
    /* sSFM1 */
    prods = 1;
    sums = 0;
    for(i=5; i<20; i++)
    {
        prods = smooth_spec_amp[i]*prods;
        sums  = sums + smooth_spec_amp[i];
    }

    if(prods>0)
    {
        prods = pow(prods,1.0/15);
    }
    else
    {
        prods=0;
    }
    sums = sums/15;

    SFM = (float)((prods+3276.8f)/(sums+3276.8f));
    sSFM[0] = 0.85f*sSFM[0] + 0.15f*SFM;

    /* sSFM2 */
    prods = 1;
    sums = 0;
    for(i=20; i<40; i++)
    {
        prods = smooth_spec_amp[i]*prods;
        sums  = sums + smooth_spec_amp[i];
    }

    if(prods>0)
    {
        prods = pow(prods,1.0/20);
    }
    else
    {
        prods =0;
    }
    sums = sums/20;
    SFM= (float)((prods+3276.8f)/(sums+3276.8f));
    sSFM[1] = 0.85f*sSFM[1] + 0.15f*SFM;
    min_sfm = sSFM[1];

    /* sSFM3 */
    prods = 1;
    sums  = 0;
    for(i=40; i<65; i++)
    {
        prods = smooth_spec_amp[i]*prods;
        sums  = sums + smooth_spec_amp[i];
    }

    if(prods>0)
    {
        prods = pow(prods,0.04);
    }
    else
    {
        prods =0;
    }
    sums = sums/25;
    SFM = (float)((prods+3276.8f)/(sums+3276.8f));
    sSFM[2] = 0.85f*sSFM[2] + 0.15f*SFM;
    if(min_sfm>sSFM[2])
    {
        min_sfm = sSFM[2];
    }

    sSFM[4] = min_sfm;

    return;
}