 
/*

This software module was originally developed by

    Kazuyuki Iijima, Masayuki Nishiguchi, and Shiro Omori (Sony Corporation)

    in the course of development of the MPEG-4 Audio standard (ISO/IEC 14496-3).
    This software module is an implementation of a part of one or more
    MPEG-4 Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio
    standard (ISO/IEC 14496-3).
    ISO/IEC gives users of the MPEG-4 Audio standards (ISO/IEC 14496-3)
    free license to this software module or modifications thereof for use
    in hardware or software products claiming conformance to the MPEG-4
    Audio standards (ISO/IEC 14496-3).
    Those intending to use this software module in hardware or software
    products are advised that this use may infringe existing patents.
    The original developer of this software module and his/her company,
    the subsequent editors and their companies, and ISO/IEC have no
    liability for use of this software module or modifications thereof in
    an implementation.
    Copyright is not released for non MPEG-4 Audio (ISO/IEC 14496-3)
    conforming products. The original developer retains full right to use
    the code for his/her own purpose, assign or donate the code to a third
    party and to inhibit third party from using the code for non MPEG-4
    Audio (ISO/IEC 14496-3) conforming products.
    This copyright notice must be included in all copies or derivative works.

    Copyright (c)1996.

*/

#include <math.h>
#include <values.h>
#include <stdio.h>

#include "hvxc.h"
#include "hvxcDec.h"
#include "hvxcCommon.h"

#define AA	0.551543
#define BB	0.152100
#define CC	0.89
#define DD	0.198025
#define GG	1.226

extern int	ipc_encMode;
extern int	ipc_decMode;


static void hpf_dec(float *bufsf)
{
    int i;
    float x3;
    static float x1old=0.,x2old=0.,x3old=0.,x4old=0.;
    
    for(i=0; i<FRM; i++){
	x3=bufsf[i]+x1old*AA + x2old*BB - ( x3old*CC + x4old*DD );
	x2old=x1old;
	x1old=bufsf[i];
	x4old=x3old;
	x3old=x3;
	bufsf[i]=x3*GG;
    }
}


typedef struct
{
    double	gainAdj;
    double	a[4], b[4];
}
CoefFltr4;

static CoefFltr4 cf4 = 
{
     1.0,

    {
        -1.998066423746901,
         1.000000000000000,
        -1.962822436245804,
         0.9684991816600951,
    },
     
   {
        -1.999633313803449,
         0.9999999999999999,
        -1.858097918647416,
        0.8654599838007603,
    }
};

typedef struct
{
    double	a[4], b[4];
}
StateFltr4;

static void hpf4ji(
float	*data,
int	size,
StateFltr4	*state,
CoefFltr4	*coef)
{
    int i;
    float x3;

    for(i = 0; i < size; i++)
    {
        x3 = data[i] + state->a[0] * coef->a[0] + state->a[1] * coef->a[1]
            - (state->a[2] * coef->a[2] + state->a[3] * coef->a[3]);
        state->a[1] = state->a[0];
        state->a[0] = data[i];
        state->a[3] = state->a[2];
        state->a[2] = x3;
        data[i] = x3;
    }
    for(i = 0; i < size; i++)
    {
        x3 = data[i] + state->b[0] * coef->b[0] + state->b[1] * coef->b[1]
            - (state->b[2] * coef->b[2] + state->b[3] * coef->b[3]);
        state->b[1] = state->b[0];
        state->b[0] = data[i];
        state->b[3] = state->b[2];
        state->b[2] = x3;
        data[i] = x3 / coef->gainAdj;
    }
}



#define AL      -2. * 1. * cos((4.0/4.0)*M_PI)
#define BBL     1.
#define CL      -2. * 0.78 * cos((3.55/4.0)*M_PI)
#define DL      0.78*0.78
#define GL      0.768


static void lpf3400(float *bufsf)
{
    int i;
    float x3;
    static float x1old=0.,x2old=0.,x3old=0.,x4old=0.;
    
    for(i=0; i<SAMPLE-OVERLAP; i++){
	x3=bufsf[i]+x1old*AL + x2old*BBL - ( x3old*CL + x4old*DL );
	x2old=x1old;
	x1old=bufsf[i];
	x4old=x3old;
	x3old=x3;
	bufsf[i]=x3*GL;
    }
}

void IPC_bpf(float *bufsf)
{
    static StateFltr4	state;

    hpf_dec(bufsf);
    hpf4ji(bufsf, FRM, &state, &cf4);
    lpf3400(bufsf);
}
