/****************************************************************************/
/*	Copyright (c) 2009, Bendor Research Pty. Ltd. All rights reserved.		*/
/*	This software is released under the GNU General Public License, version	*/
/*	3, with the exemptions that 1) the header files installed by this 	 	*/
/*	package can be included in closed-source code and 2) the libraries		*/
/*	built by this package can be statically linked into a closed-source 	*/
/*	binary. See the file LICENSE for the details.							*/
/*	This software is provided "AS IS", without any warranty or guarantee.	*/
/*	By using this software you acknowledge that neither Bendor Research nor	*/
/*	any of its personnel or affiliates can be held liable for any damages,	*/
/*	including, but not limited to, loss of business, loss of money, loss of */
/*	life, loss of reputation, arising out of this software being faulty or	*/
/*	not performing as advertised, even if Bendor Research was aware of such	*/
/*	faults in the software. You use this software at your own risk, any and */
/*	all liabilities that arise out of your using this software are strictly	*/
/*	yours.																	*/
/****************************************************************************/

/****************************************************************************/
/*		Everything below is only for documenting assembly functions			*/
/****************************************************************************/

/** @addtogroup fixp */
/** @{ */

/**
*	Complex fast Fourier transform operating on 32-bit fixpoint data.
*
*	This function performs a discrete Fourier transformation or inverse
*	discrete Fourier transformation on a block of data. The number of data
*	elements must be a power of two. The elements are represented as complex
*	fixpoint numbers, both the real and imaginary parts occupying a 32-bit
*	word.
*	<br><br>
*	Since the Fourier transformation is a linear operator, the position
*	of the radix point is irrelevant. However, there is a restriction that
*	you can have at most 29 significant bits. Therefore, if your radix
*	point is after the LSB of the word, your data is integers in the range
*	of +/- 0x1ffffffff. On the other end, if your radix point is after the
*	third most significant bit of the word, the data represents values
*	between (-1,+1) with 29 fractional bits; you can have anything in between
*	these two extremities.
*	<br><br>
*	Mathematically the definition of the Fourier transform and its inverse
*	involves a scale factor. This implementation does not use the proper
*	mathematical scaling. Instead, it does the transform the following way:
*	If you treat your data as fixpoint numbers with 29 bits fractional part
*	and your data is guaranteed to be within (-1,+1), then the forward
*	transform will yield coefficient values in the range of (-1,+1) for
*	F(0) and F(N/2) and (-0.5,+0.5) for all others, in the same fixpont format.
*	If you now inverse transform that array, you will get your original data
*	back (except for round-off errors).
*	<br><br>
*	Since the transform operates on fixpoint data, it is important that you
*	provide as many bits as possible, to minimise calculation artefacts.
*	If your data set is say 12-bit integers, you should shift them up by 17 bits
*	before passing it to the function and shift the result down by 17 bits.
*	This will reduce the effect of rounding errors (effectively a random noise
*	that has a magnutide of a few LSBs).
*	<br><br>
*	The transformation is in place, the transformation result replaces
*	the data. For the sake of simplicity we will call the original and the
*	transformed space time domain and frequency domain, respectively, so that
*	we can use simple engineering terms.
*	If you have N data points in the time domain, corresponding to 0, t, 2t,
*	3t, ..., (N-1)t where t is the sampling period and you transform it, you
*	will get the Fourier coefficients at 0, +f, -f, +2f, -2f, .. +(N/2-1)f,
*	-(N/2-1)f and (N/2)f, where f is 1/(N*t). The first element is usually
*	called the DC component while the last element, (N/2)f is the Nyquist
*	frequency, i.e. half of 1/t, the sampling frequency.
*	Since everything is complex, you have an array of 2N integers. The data is
*	arranged in the array as follows (Re and Im denote the real and imaginary
*	parts of a complex number, respectively):
*	@code
*		Array		Time			Freq.
*		index		domain			domain
*		----------------------------------
*		0			Re 0			Re 0
*		1			Im 0			Im 0
*		2			Re t			Re +f
*		3			Im t			Im +f
*		4			Re 2t			Re +2f
*		5			Im 2t			Im +2f
*		...			...				...
*		N-2			Re (N/2-1)t		Re +(N/2-1)f
*		N-1			Im (N/2-1)t		Im +(N/2-1)f
*		N			Re (N/2)t		Re (N/2)f
*		N+1			Im (N/2)t		Im (N/2)f
*		N+2			Re (N/2+1)t		Re -(N/2-1)f
*		N+3			Im (N/2+1)t		Im -(N/2-1)f
*		...			...				...
*		2N-4		Re (N-2)t		Re -2f
*		2N-3		Im (N-2)t		Im -2f
*		2N-2		Re (N-1)t		Re -f
*		2N-1		Im (N-1)t		Im -f
*	@endcode
*	To do the transformation, the routine needs a table of the sine
*	values between 0 and PI/2. The table has N/4+1 elements.
*	This table can be constructed by the following simple C routine:
*	@code
*	#include <math.h>
*
*	#define	PIo2	1.570796326794896619256404479703093102216
*	#define SCALE	1073741824
*
*
*	void fft32c_table_gen( int *table, int pow2 )
*	{
*	int		i, n;
*	double	s;
*
*		n = 1 << ( pow2 - 2 );
*		s = PIo2 / n;
*
*		for ( i = 0 ; i <= n ; i++ )
*
*			table[ i ] = round( sin( s * i ) * SCALE );
*	}
*	@endcode
*
*	This table is consulted in the innermost loop of the transform. Therefore,
*	the difference between the access cost of data stored in internal RAM
*	or in the FLASH will have a direct, perceptible impact on the speed
*	of the function. It depends on the chip in question, on an LPC23xx chip
*	you can expect a 10-15% speed penalty if you store the table in FLASH.
*	<br><br>
*	This is a complex transform; if you want to transform purely real data,
*	you should look at the fft32r() function which transforms between
*	real time and complex frequency domains.
*
*	@param	data	Pointer to an array of integers, the array is
*					<tt>2<sup>pow2+1</sup></tt> elements long. The array will
*					be transformed in place.
*
*	@param	coef	Pointer to an array of integers that represent the values
*					of the <i>sin(x)</i> function values between 0 and PI/2.
*					The array has <tt>2<sup>pow2-2</sup>+1</tt> elements.
*
*	@param	pow2	The base-2 logarithm of the number of data points. This
*					number must be at least 2, that is, the smallest transform
*					you can perform is 4 points. Note that the function does
*					not check for validity of this argument, if you pass
*					an incorrect number, the routine will crash.
*
*	@param	idft	If this argument is zero, then a forward transform is
*					performed, if it is non-zero, then inverse transform is
*					performed.
*/

void	fft32c( int *data, const int *coef, unsigned pow2, int idft );

/**
*	Real valued fast Fourier transform operating on 32-bit fixpoint data.
*
*	This function performs a discrete Fourier transformation or inverse
*	discrete Fourier transformation on a block of data. The number of data
*	elements must be a power of two. The data elements are represented as
*	fixpoint numbers while the transformed domain is represented as fixpoint
*	complex numbers.
*	<br><br>
*	The restrictions on the data format are identical to that of the fft32c()
*	function, as are the scaling properties, except that for this function
*	the resulting coefficients are all in the (+1,-1) range, that is, there is
*	no difference between the 0th and (N/2)f coefficients and the rest.
*	<br><br>
*	The transformation is in place, the transformation result replaces
*	the data. Using the same terms as for the fft32c() function, the data
*	arrangement in memory is the following; note that for real-valued
*	transforms the imaginary part of the DC and the Nyquist frequency
*	coefficients are always zero, thus omitted:
*	@code
*		Array		Time			Freq.
*		index		domain			domain
*		----------------------------------
*		0			0				Re 0
*		1			t				Re +(N/2)f
*		2			2t				Re +f
*		3			3t				Im +f
*		4			4t				Re +2f
*		5			5t				Im +2f
*		...			...				...
*		N-4			(N-4)t			Re +(N/2-2)f
*		N-3			(N-3)t			Im +(N/2-2)f
*		N-2			(N-2)t			Re +(N/2-1)f
*		N-1			(N-1)t			Im +(N/2-1)f
*	@endcode
*	To do the transformation, the routine needs a table of the sine
*	values between 0 and PI/2. The table has N/4+1 elements.
*	This table can be constructed by the following simple C routine,
*	note that it is different from the one used for fft32c():
*	@code
*	#include <math.h>
*
*	#define	PIo2	1.570796326794896619256404479703093102216
*	#define SCALE	1073741824
*
*
*	void fft32r_table_gen( int *table, int pow2 )
*	{
*	int		i, n;
*	double	s, o;
*
*		n = 1 << ( pow2 - 3 );
*		s = PIo2 / n;
*		o = -s / 2;
*
*		for ( i = 0 ; i <= n ; i++ )
*
*			table[ i ] = round( sin( s * i ) * SCALE );
*
*		for ( i = 1 ; i < n ; i++ )
*
*			table[ n + i ] = round( sin( s * i + o ) * SCALE );
*	}
*	@endcode
*
*	The effect of storing the table in RAM or in  FLASH is the same
*	as with the fft32c() function.
*	<br><br>
*	This function handles only real data in the time domain, if you need
*	complex to complex Fourier transform, you should use the fft32c() function.
*
*	@param	data	Pointer to an array of integers, the array is
*					<tt>2<sup>pow2</sup></tt> elements long. The array will
*					be transformed in place.
*
*	@param	coef	Pointer to an array of integers that represent the values
*					of the <i>sin(x)</i> function values between 0 and PI/2.
*					The array has <tt>2<sup>pow2-2</sup>+1</tt> elements.
*					Note that the values are not in simple linearly increasing
*					angular order.
*
*	@param	pow2	The base-2 logarithm of the number of real data points.
*					This number must be least 3, that is, the smallest transform
*					you can perform is 8 real (and thus 4 complex) points. Note
*					that the function does not check for validity of this
*					argument, if you pass an incorrect number, the routine will
*					crash.
*
*	@param	idft	If this argument is zero, then a forward transform is
*					performed, if it is non-zero, then inverse transform is
*					performed.
*/

void	fft32r( int *data, const int *coef, unsigned pow2, int idft );

/**
*	Complex fast Fourier transform operating on 16-bit fixpoint data.
*
*	This function performs a discrete Fourier transformation or inverse
*	discrete Fourier transformation on a block of data. The number of data
*	elements must be a power of two. The elements are represented as complex
*	fixpoint numbers, both the real and imaginary parts occupying a 16-bit
*	word.
*	<br><br>
*	This function is equivalent to the fft32c() function, except that
*	both the data and the coefficients are stored in 16-bit shorts instead
*	of 32-bit ints. This has the following consequences:
*	-	Your data can have at most 13 significant bits, thus, if you interpret
*		it as integers, your range is [-0x1fff,+0x1fff] and if you interpret
*		it as a fixpoint number with 3 integer and 13 fractional bits then
*		your valid range is in (-1.0,+1.0).
*	-	When generating the sin() table that is passed in the \p coef argument,
*		\p \#define \p SCALE should be set to 32768.
*
*	For all other aspects the description of fft32c() applies. Note that the
*	array of shorts that is the data must be aligned at an int boundary, the
*	coefficient array can be aligned on a short boundary.
*
*	@param	data	Pointer to an array of short integers, the array is
*					<tt>2<sup>pow2+1</sup></tt> elements long. The array will
*					be transformed in place.
*					Although it is an array of <tt>short</tt>s, it <b>must
*					be</b> aligned on a 32-bit word boundary.
*
*	@param	coef	Pointer to an array of shorts that represent the values
*					of the <i>sin(x)</i> function values between 0 and PI/2.
*					The array has <tt>2<sup>pow2-2</sup>+1</tt> elements.
*
*	@param	pow2	The base-2 logarithm of the number of data points. This
*					number must be at least 2, that is, the smallest transform
*					you can perform is 4 points. Note that the function does
*					not check for validity of this argument, if you pass
*					an incorrect number, the routine will crash.
*
*	@param	idft	If this argument is zero, then a forward transform is
*					performed, if it is non-zero, then inverse transform is
*					performed.
*/

void	fft16c( short *data, const short *coef, unsigned pow2, int idft );

/**
*	Real fast Fourier transform operating on 16-bit fixpoint data.
*
*	This function performs a discrete Fourier transformation or inverse
*	discrete Fourier transformation on a block of data. The number of data
*	elements must be a power of two. The data elements are represented as
*	fixpoint numbers while the transformed domain is represented as fixpoint
*	complex numbers.
*	<br><br>
*	This function is equivalent to the fft32r() function, except that
*	both the data and the coefficients are stored in 16-bit shorts instead
*	of 32-bit ints. This has the following consequences:
*	-	Your data can have at most 13 significant bits, thus, if you interpret
*		it as integers, your range is [-0x1fff,+0x1fff] and if you interpret
*		it as a fixpoint number with 3 integer and 13 fractional bits then
*		your valid range is in (-1.0,+1.0).
*	-	When generating the sin() table that is passed in the \p coef argument,
*		\p \#define \p SCALE should be set to 32768.
*
*	For all other aspects the description of fft32r() applies. Note that the
*	array of shorts that is the data must be aligned at an int boundary, the
*	coefficient array can be aligned on a short boundary.
*
*	@param	data	Pointer to an array of short integers, the array is
*					<tt>2<sup>pow2</sup></tt> elements long. The array will
*					be transformed in place.
*					Although it is an array of <tt>short</tt>s, it <b>must
*					be</b> aligned on a 32-bit word boundary.
*
*	@param	coef	Pointer to an array of shorts that represent the values
*					of the <i>sin(x)</i> function values between 0 and PI/2.
*					The array has <tt>2<sup>pow2-2</sup>+1</tt> elements.
*					Note that the values are not in simple linearly increasing
*					angular order.
*
*	@param	pow2	The base-2 logarithm of the number of real data points.
*					This number must be least 3, that is, the smallest transform
*					you can perform is 8 real (and thus 4 complex) points. Note
*					that the function does not check for validity of this
*					argument, if you pass an incorrect number, the routine will
*					crash.
*
*	@param	idft	If this argument is zero, then a forward transform is
*					performed, if it is non-zero, then inverse transform is
*					performed.
*/

void	fft16r( short *data, const short *coef, unsigned pow2, int idft );

/**
*	Fixpoint square root.
*
*	This function takes a number, which is in 1.31 fixpoint format, that is,
*	the radix point is after the MSB of the word. The return value is the
*	square root of that number, in the same format.
*
*	The result is accurate to 31 significant bits
*
*	@param		x		The number to calculate the square root of, it should
*						be in 1.31 fixpoint format and within the range of
*						[0.0,2.0).
*
*	@return				The square root of x, in the same 1.31 format and in
*						the range of [0.0,sqrt(2))
*/

unsigned	sqrt32( unsigned x );

/**
*	Reciprocal of a 32-bit fixpoint number.
*
*	This function calculates the reciprocal of a number. The argument is
*	in 0.32 format (that is, the radix point is just left of its MSB) and
*	it must be in the range of (1/4,1). The result is in 2.30 format
*	(the radix point is between bit 30 and bit 29) and is in the range of
*	[1,4). Note that an argument of 1/4 (corresponding to the 32-bit integer
*	value of 0x40000000) or less generates a result that is not representable
*	in the 2.30 format, therefore the function will return garbage.
*
*	The result is accurate to 31 significant bits.
*
*	@param	x	A number in 0.32 format, in the range of (1/4,1)
*	@return		1/x, in 2.30 format, in the range of [1,4)
*/

unsigned	rec32( unsigned x );

/**
*	Fixpoint multiply-accumulate function.
*
*	The function multiplies its first two arguments as signed fixpoint
*	numbers and then adds the third argument to the product and returns
*	the result. The three arguments can all have different radix position.
*	The result has the same radix position as that of the third argument.
*	<br><br>
*	The last argument tells the function how to format the multiplication
*	result to mach the format of the additive argument.
*	The number represents the sum of the number of integer bits in the
*	multiplicands, minus the number of integer bits in the accumulator.
*	For example, if all numbers are in 4.28 format then the last argument
*	should be (4+4)-4 = 4. If one of the multiplicands is an integer (that
*	is, it is in 32.0 format) while the other multiplicand is a 8.24 format
*	and the accumulator is in 16.16 format then the last argumen should be
*	(32+8)-16 = 24. Note that this number must be between 32 and 0.
*
*	@param	x	One of the multiplicands
*	@param	y	The other multiplicand
*	@param	a	The additive tag
*	@param	s	The scale factor, the difference between the number of
*				integer bits in the multiplication result and in the
*				additive argument, between 0 and 32.
*
*	@return		The value of a + SCALE_AND_ROUND( x * y )
*/

int		mac32( int x, int y, int a, unsigned s );

/**
*	Base-2 logarithm of a fixpoint number.
*
*	The function calculates the base-2 logarithm of its argument plus 1.
*	The argument is interpreted in 0.32 format and is in the range of
*	(1,0]. The function then adds 1.0 to the argument and calculates the
*	logarithm of that number. The value returned is in the same 0.32 format.
*
*	<tt>log32(x) := log<sub>2</sub>( x + 1 )</tt>
*
*	Using this function you can easily build functions that can calculate the
*	logarithm of numbers with arbitrary radix point location. Also, changing
*	the base of the logarithm to values other that 2 is trivial. The ldzcnt()
*	and umul32x32_64() functions will prove to be very useful for that.
*
*	The result is accurate to 29 bits.
*
*	@param	x		The function argument
*	@return			The base-2 logarithm of 1+x
*/

unsigned	log32( unsigned x );

/**
*	Base-2 exponential of a fixpoint number.
*
*	The function calculates the base-2 exponential of its argument and
*	returns the result minus 1.
*	The argument is interpreted in 0.32 format, (the radix point is just left
*	the MSB), that is 0x80000000 represents 0.5. Thus, the argument is in the
*	range of (1,0]. The function raises 2 to the power of the argument and
*	returns the fractional part of the result, in the same 0.32 format. The
*	integer part of the result, which is always 1, is discarded.
*
*	<tt>exp32(x) := 2<sup>x</sup> - 1</tt>
*
*	Using this function as the core, it is very easy to write functions that
*	use a different radix point location or a base other than 2.
*
*	The result is accurate to 29 bits.
*
*	@param	x		The function argument
*	@return			The fractional part of the base-2 exponent of x
*/

unsigned	exp32( unsigned x );

/** @} */

