//Adaptpredict_pcm.c Adaptive predictor to cancel interference 

#define beta 1E-13                //rate of convergence      
#define N 60                      //# of coefficients of adapt FIR 
#define NS 256                    //size of wideband's buffer  
#define LEFT 1                    //left channel
#define RIGHT 0                   //right channel
const short bufferlength = NS;    //buffer length for wideband signal
short splusn[N+1];     		    //buffer wideband signal+interference 
float w[N+1];          		    //buffer for weights of adapt FIR  
float delay[N+1];      		    //buffer for input to adapt FIR
float Fs = 48000.0;               //for variable Fs
volatile union {unsigned int uint; short channel[2];}CODECData;

interrupt void c_int11()          //ISR
{                         
 static short buffercount=0;      //init buffer
 short i;
 float yn, E; 		          //yn=out adapt FIR, error signal
 short wb_signal;			    //wideband desired signal
 short noise;			    //external interference 

 CODECData.uint = input_sample(); //input left and right as 32-bit
 wb_signal = (float) CODECData.channel[LEFT]; //desired on left channel
 noise = (float) CODECData.channel[RIGHT];    //noise on right channel

 splusn[0] = (wb_signal + noise); //wideband signal+interference
 delay[0] = splusn[3];            //delayed input to adaptive FIR 
 yn = 0;                          //init output of adaptive FIR 
 
 for (i = 0; i < N; i++)
   yn += (w[i] * delay[i]);       //output of adaptive FIR filter 
 
 E = splusn[0] - yn;              //(wideband+noise)-out adapt FIR
 
 for (i = N-1; i >= 0; i--)         
  {
   w[i] = w[i]+(beta*E*delay[i]); //update weights of adapt FIR 
   delay[i+1] = delay[i];         //update buffer delay samples 
   splusn[i+1] = splusn[i];       //update buffer corrupted wideband 
  } 
 
 buffercount++;                   //incr buffer count of wideband 
 if (buffercount >= bufferlength) //if buffer count=length of buffer
   buffercount = 0;		    //reinit count  
 output_left_sample((short)E);    //overall output from left channel
 return;
}

void main()
{
 int T = 0;
 for (T = 0; T < N; T++)          //init variables
  {
   w[T] = 0.0;			    //init weights of adaptive FIR
   delay[T] = 0.0;		    //init buffer for delay samples 
   splusn[T] = 0;			    //init wideband+interference
  } 
 comm_intr();                     //init DSK, codec, McBSP
 while(1);                        //infinite loop
}