/**************************************************************************/
/**************************************************************************/
/*
filter3.c: This file contains the analysis code for the third order
	filter H[N] = (1,-3,3,-1).

*/
/**************************************************************************/
/*
Copyright, 1995 Atari Corporation.
Written for Atari by Highlight Software Solutions.
*/
/**************************************************************************/

#include "hdef.h"	/* this file contains the data types and constants. */


/**************************************************************************/
/*
Function: filter3:

definition:
	This function implements a third order filter H[N] = (1,-3, 3,-1).
	The calling parameters choose the number of elements to act on.
	The calling parameters include an array of previous elements to
		allow for continuous states.
	The calling parameters also include an input block of elements
		and a pointer to the desired output block of elements.
	The array returns the bits needed to pack the outputs of the
		filter for use by the calling function in determining the
		winning filter.
arguments:
	statearray: this pointer points to an array of HWORDS that must
		contain the last samples from the previous block equal
		to the order of the filter. This 3rd order filter uses
		the first, second, and third elements in this list.
	elements: the number of elements to use this digital filter over.
	datain: this pointer points to a sequential array of HWORDS that
		contain the input words to the filter.
	fout: this pointer points to a sequential array of HWORDS that
		will contain the output words from the filter after
		completion of the filter.
-------------------------------------------------------
returns:
	an HINT with the maximum number of bits needed
	to pack the output of the filter.
-------------------------------------------------------
example:
packbits = filter3(statearray, 32, databuf, outbuf);
calls this function which implements the 3rd order filter on 32 elements
	starting at databuf, places the output at outbuf, and returns the
	number of bits needed to pack the filter in packbits.
	The elements at statearray are assumed to have preceeded the elements
	at databuf.
	For this 3rd order filter, statearray[0],statearray[1] and
		statearray[2] are used from this list.
*/
/**************************************************************************/

HINT filter3(LPHWORD statearray, HINT elements, LPHWORD datain, LPHWORD fout)
{
HINT i;
HINT packbits;
HLONG temp;

for (i = 0; i < elements; i++) {
	switch(i) {
		case 0:
			temp = ((HLONG) datain[0]) - ((HLONG) 3) * ((HLONG) statearray[0]) + ((HLONG) 3) * ((HLONG) statearray[1]) - ((HLONG) statearray[2]);
			if (((temp & HIGHVALUEMASK) != 0) && ((temp & HIGHVALUEMASK) != HIGHVALUEMASK)) {
				/* overflow, we can't use this filter */
				return(TOOMANYBITS);
			}
			fout[i] = (HINT) temp;
			break;
		case 1:
			temp = ((HLONG) datain[1]) - ((HLONG) 3) * ((HLONG) datain[0]) + ((HLONG) 3) * ((HLONG) statearray[0]) - ((HLONG) statearray[1]);
			if (((temp & HIGHVALUEMASK) != 0) && ((temp & HIGHVALUEMASK) != HIGHVALUEMASK)) {
				/* overflow, we can't use this filter */
				return(TOOMANYBITS);
			}
			fout[i] = (HINT) temp;
			break;
		case 2:
			temp = ((HLONG) datain[2]) - ((HLONG) 3) * ((HLONG) datain[1]) + ((HLONG) 3) * ((HLONG) datain[0]) - ((HLONG) statearray[0]);
			if (((temp & HIGHVALUEMASK) != 0) && ((temp & HIGHVALUEMASK) != HIGHVALUEMASK)) {
				/* overflow, we can't use this filter */
				return(TOOMANYBITS);
			}
			fout[i] = (HINT) temp;
			break;
		default:
			temp = ((HLONG) datain[i]) - ((HLONG) 3) * ((HLONG) datain[i - 1]) + ((HLONG) 3) * ((HLONG) datain[i - 2]) - ((HLONG) datain[i - 3]);
			if (((temp & HIGHVALUEMASK) != 0) && ((temp & HIGHVALUEMASK) != HIGHVALUEMASK)) {
				/* overflow, we can't use this filter */
				return(TOOMANYBITS);
			}
			fout[i] = (HINT) temp;
			break;
	}

}
packbits = maxbits(elements, fout);
return(packbits);
} /* filter3 */



