/*************************************************************************
 * This code is written by N. Kehtarnavaz and N. Kim as part of the 
 * textbook "Digital Signal Processing System-Level Design Using LabVIEW".
 *************************************************************************/

#include "target.h" 
#include <rtdx.h>  

#define N 32 //filter length
#define kBUFFER_SIZE 64

float h[N] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float samples[N];

RTDX_CreateInputChannel(cin1);
RTDX_CreateInputChannel(cin2);
RTDX_CreateOutputChannel(cout1);
RTDX_CreateOutputChannel(cout2);

void main()
{	
	float input1[kBUFFER_SIZE];
	float input2[kBUFFER_SIZE];
	float output[kBUFFER_SIZE];
	float e[kBUFFER_SIZE];
	
	int i, j;
	float  stemp, stemp2;
			
	for( i = 0 ; i < N ; i++ )
		samples[i] = 0;
	
	// Target initialization for RTDX
	TARGET_INITIALIZE();

	/*enable RTDX channels*/
	
	RTDX_enableInput(&cin1);
	RTDX_enableInput(&cin2);
	RTDX_enableOutput(&cout1);
	RTDX_enableOutput(&cout2);
	
	for (;;)	/* Infinite message loop. */
	{
		/* Wait for input sample */
		while(!RTDX_read(&cin1, input1, sizeof(input1)));
		while(!RTDX_read(&cin2, input2, sizeof(input2)));
		
		for (j = 0; j < kBUFFER_SIZE; j++)
		{				
			//update array samples
			for(i = N-1; i > 0; i-- )
				samples[i] = samples[i-1];
	
			samples[0] = input1[j];

			stemp =0;
			
			// FIR Filtering
			for( i = 0 ; i < N ; i++ )
				stemp += (samples[i] * h[i]);
			
			output[j] = stemp;
			
			e[j] =  input2[j] - stemp;
			
			stemp = (0.001 * e[j]);
			
			// Update Coefficient
			for(i = 0; i < N; i++)
			{
				stemp2 = (stemp * samples[i]);
				h[i] = h[i] + stemp2; 
			}
		}	
		
		/* Write scaled data back to host. */
		RTDX_write(&cout1, output, sizeof(output));
		RTDX_write(&cout2, e, sizeof(e));
	
	}
}

