<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.ocetechnology.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Fft.h</id>
	<title>Fft.h - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.ocetechnology.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Fft.h"/>
	<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=Fft.h&amp;action=history"/>
	<updated>2026-04-04T11:32:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=Fft.h&amp;diff=380&amp;oldid=prev</id>
		<title>imported&gt;Bkavanagh: Created page with &quot; /*   * fft.h   *   *  Created on: Jan 21, 2016   *  Author: mryan   */  #ifndef FFT_H_  #define FFT_H_    #include &lt;math.h&gt;  #include &lt;time.h&gt;  #include &lt;unistd.h&gt;    // assu...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=Fft.h&amp;diff=380&amp;oldid=prev"/>
		<updated>2020-09-14T15:53:27Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot; &lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;* fft.h   *   *  Created on: Jan 21, 2016   *  Author: mryan: &lt;/span&gt;  #ifndef FFT_H_  #define FFT_H_    #include &amp;lt;math.h&amp;gt;  #include &amp;lt;time.h&amp;gt;  #include &amp;lt;unistd.h&amp;gt;    // assu...&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:53, 14 September 2020&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en-GB&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>imported&gt;Bkavanagh</name></author>
	</entry>
	<entry>
		<id>https://wiki.ocetechnology.com/mediawiki/index.php?title=Fft.h&amp;diff=11&amp;oldid=prev</id>
		<title>imported&gt;Bkavanagh: Created page with &quot; /*   * fft.h   *   *  Created on: Jan 21, 2016   *  Author: mryan   */  #ifndef FFT_H_  #define FFT_H_    #include &lt;math.h&gt;  #include &lt;time.h&gt;  #include &lt;unistd.h&gt;    // assu...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.ocetechnology.com/mediawiki/index.php?title=Fft.h&amp;diff=11&amp;oldid=prev"/>
		<updated>2020-09-14T15:53:27Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot; &lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;* fft.h   *   *  Created on: Jan 21, 2016   *  Author: mryan: &lt;/span&gt;  #ifndef FFT_H_  #define FFT_H_    #include &amp;lt;math.h&amp;gt;  #include &amp;lt;time.h&amp;gt;  #include &amp;lt;unistd.h&amp;gt;    // assu...&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; /*&lt;br /&gt;
  * fft.h&lt;br /&gt;
  *&lt;br /&gt;
  *  Created on: Jan 21, 2016&lt;br /&gt;
  *  Author: mryan&lt;br /&gt;
  */&lt;br /&gt;
 #ifndef FFT_H_&lt;br /&gt;
 #define FFT_H_&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;lt;math.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;time.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 // assuming basic number type is float (for now)&lt;br /&gt;
 # ifndef fft_scalar&lt;br /&gt;
 #   define fft_scalar float&lt;br /&gt;
 # endif&lt;br /&gt;
 &lt;br /&gt;
 // (in-phase, quadrature) data is treated as a complex number&lt;br /&gt;
 typedef struct {&lt;br /&gt;
     fft_scalar re;					// real, i.e. in-phase&lt;br /&gt;
     fft_scalar im;					// imaginary, i.e. quadrature&lt;br /&gt;
 }fft_cpx;&lt;br /&gt;
 &lt;br /&gt;
 // each CPU has a struct of this type set up in SRAM&lt;br /&gt;
 typedef struct {&lt;br /&gt;
     unsigned int status;&lt;br /&gt;
     unsigned int cinadrs;&lt;br /&gt;
     unsigned int lenP2;				// power of 2 that gives length&lt;br /&gt;
     unsigned int begin;&lt;br /&gt;
     unsigned int nextbegin;&lt;br /&gt;
     unsigned int oddadd;&lt;br /&gt;
     unsigned int startP2;			// power of 2 that gives butterfly to start with&lt;br /&gt;
     unsigned int twadrs;&lt;br /&gt;
     unsigned int toffset;&lt;br /&gt;
     unsigned int tinc;&lt;br /&gt;
     unsigned int normalise;&lt;br /&gt;
     unsigned int arrange;&lt;br /&gt;
     unsigned int realonly;&lt;br /&gt;
     unsigned int secondpass;&lt;br /&gt;
     unsigned int spare1;			// bring up to a 16 word boundary&lt;br /&gt;
     unsigned int spare2;&lt;br /&gt;
 }fft_cpu;&lt;br /&gt;
 &lt;br /&gt;
 #define FFT_WORK_MASK   1			// pick off last bit&lt;br /&gt;
 #define FFT_NOWORK		0			// nothing to be done/finished&lt;br /&gt;
 #define FFT_START		1			// work to be done/working&lt;br /&gt;
 &lt;br /&gt;
 #define MAX_CPUS 		4&lt;br /&gt;
 #define LAST_CPU		8			// 0x1000&lt;br /&gt;
 #define START_CPU_INDEX	0			// N.B. fft_multi() assumes is 0, CPU that starts on power up&lt;br /&gt;
 &lt;br /&gt;
 #define IRQMP_ADRS		0x80000210  // address of multiprocessor status register&lt;br /&gt;
 #define CPUS_PM1_MASK	0xf0000000	// tells how many CPUs in system minus 1&lt;br /&gt;
 #define CPUS_PM1_SHIFTS 28			// shift them to low order&lt;br /&gt;
 #define	CPUS_MASK    	0xf			// bits used to power-up CPUs&lt;br /&gt;
 #define CPU_START_PAUSE	1000		// pause between and after CPU startups&lt;br /&gt;
 &lt;br /&gt;
 // set up space for the various arrays. S698PM SRAM is 32 Mbyte from 0x40000000.&lt;br /&gt;
 #define FFT_SRAM 	 	0x60000000				// half way&lt;br /&gt;
 #define FFT_FLAGS	 	FFT_SRAM+0x80000&lt;br /&gt;
 #define FFT_CIN  	 	FFT_SRAM+0x100000		// space for 2 power 20 bytes,&lt;br /&gt;
 #define FFT_RAIN	 	FFT_SRAM+0x200000		// i.e. 2 power 18 doubles&lt;br /&gt;
 #define FFT_TWIDDLES 	FFT_SRAM+0x400000		// i.e. 2 power 17 complex nos&lt;br /&gt;
 #define FFT_COUT	 	FFT_SRAM+0x600000&lt;br /&gt;
 #define FFT_MAP			FFT_SRAM+0x800000		// maps input index to rearranged index&lt;br /&gt;
 &lt;br /&gt;
 #define FFT_MIN_LENP2	5			// minimum input 32 (in-phase,quadrature)&lt;br /&gt;
 #define FFT_MAX_LENP2	17			// for consistency with space allocation above&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * FUNCTION DECLARATIONS&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  *  The functions declared below are used to create an FFT&lt;br /&gt;
  *  using 1, 2 or 4 processors acting in parallel.&lt;br /&gt;
  *&lt;br /&gt;
  *	At present the input array length must be a power of 2.&lt;br /&gt;
  *&lt;br /&gt;
  *  At present the input data in each (in-phase, quadrature) pair must be C floats.&lt;br /&gt;
  *&lt;br /&gt;
  *	The processing is based on arrays of complex numbers corresponding to&lt;br /&gt;
  *	the (in-phase, quadrature) data.&lt;br /&gt;
  *&lt;br /&gt;
  *	If the input data is in-phase only, the input array will have 0 in each entry's&lt;br /&gt;
  *	quadrature component. An option is provided to allow this be exploited so as&lt;br /&gt;
  *	to get the result roughly twice as fast&lt;br /&gt;
  *&lt;br /&gt;
  *  Usage:&lt;br /&gt;
  *		0.	Create an array holding the in-phase and quadrature data&lt;br /&gt;
  *			as complex numbers (fft_cpx).&lt;br /&gt;
  *&lt;br /&gt;
  *			At present, the length of this array must be a power of 2.&lt;br /&gt;
  *			At present, data elements should be of the C float type.&lt;br /&gt;
  *&lt;br /&gt;
  *		1.	The complex array must be arranged in an order suitable&lt;br /&gt;
  *			for 'discrimination in time' (DIT) processing.&lt;br /&gt;
  *&lt;br /&gt;
  *			This can be done as the entries are made one at a time.&lt;br /&gt;
  *			An index array can first be created for use to map&lt;br /&gt;
  *			successive input to the correct position in the&lt;br /&gt;
  *			array. This can be stored in ROM, and reused to allocate data&lt;br /&gt;
  *			as it comes in to the appropriate place in the array.&lt;br /&gt;
  *&lt;br /&gt;
  *			The function fftArrangeIndex() below is provided for&lt;br /&gt;
  *			this purpose.&lt;br /&gt;
  *&lt;br /&gt;
  *			If the input data is not rearranged as it arrives,&lt;br /&gt;
  *			a parameter can be set to cause rearrangement to be done&lt;br /&gt;
  *			in parallel in the first phase of FFT processing on each CPU.&lt;br /&gt;
  *			In that case the FFT result does not overwrite the input data,&lt;br /&gt;
  *			but can be found in the FFT_RAIN area defined below.&lt;br /&gt;
  *&lt;br /&gt;
  *			Alternatively, if the array already exists (as an array of complex numbers),&lt;br /&gt;
  *			it can be rearranged in situ using fftArrangeIn(),&lt;br /&gt;
  *			or as a new complex array using fftArrangOut().&lt;br /&gt;
  *&lt;br /&gt;
  *			The data in the rearranged array is overwritten by the FFT&lt;br /&gt;
  *			results, so if it is desired to keep the original data&lt;br /&gt;
  *			either the parallel rearrangement parameter should be set&lt;br /&gt;
  *			or the fftArrangeOut() function should be used.&lt;br /&gt;
  *&lt;br /&gt;
  *			To avoid the overhead of rearrangement it is best to rearrange&lt;br /&gt;
  *			the data as it arrives, if possible.&lt;br /&gt;
  *&lt;br /&gt;
  *		3.	The 'twiddles' array, containing complex roots of unity,&lt;br /&gt;
  *			must be created. This is half the length of the input&lt;br /&gt;
  *			array of complex numbers, as due to symmetry only half&lt;br /&gt;
  *			of the roots need to be created and stored.&lt;br /&gt;
  *			The function fillTwiddles() is provided for this purpose.&lt;br /&gt;
  *&lt;br /&gt;
  *		N.B.	If the size of the data array does not change,&lt;br /&gt;
  *				the twiddles array can be stored in ROM.&lt;br /&gt;
  *				Two versions are needed in that case, one for the forward FFT,&lt;br /&gt;
  *				one for the inverse FFT. Both can be generated using fillTwiddles().&lt;br /&gt;
  *&lt;br /&gt;
  *		4.	The appropriately arranged complex input array is passed to fftMulti(),&lt;br /&gt;
  *			together with the twiddles array and which processors to use.&lt;br /&gt;
  *			The result overwrites the original data in the rearranged array.&lt;br /&gt;
  *&lt;br /&gt;
  *		5.	Other than input rearrangement, no copying is involved in passing data&lt;br /&gt;
  *			to the different processors, each is given a reference to a contiguous&lt;br /&gt;
  *			portion of the input array.&lt;br /&gt;
  *			A reference to the twiddles array is also passed, though the entries&lt;br /&gt;
  *			used in this by a processor are not contiguous.&lt;br /&gt;
  *&lt;br /&gt;
  *		6.	All stages of processing up to the last two (4 CPUs) or last one (2 CPUs)&lt;br /&gt;
  *			are done independently on the CPUs, with no interaction between them.&lt;br /&gt;
  *			The last stage or stages require results generated by a different CPU,&lt;br /&gt;
  *			so must wait for the previous stages to complete before progressing.&lt;br /&gt;
  *&lt;br /&gt;
  *		7.	If the 'real only', i.e in-phase only, option is selected any 'imaginary',&lt;br /&gt;
  *			i.e quadrature, component in the input is ignored and the input array compressed&lt;br /&gt;
  *			into half its length with the entries in the remaining half set to (0.0,0.0).&lt;br /&gt;
  *			The processing is done roughly twice as fast.&lt;br /&gt;
  *			Only the positive frequency components are produced,&lt;br /&gt;
  *			the negative frequency components are easily derived if needed by taking&lt;br /&gt;
  *			the complex conjugates of the positive frequency components,&lt;br /&gt;
  *			i.e. changing the sign of the imaginary component and leave the rest the same.&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * FUNCTION DECLARATIONS&lt;br /&gt;
  */&lt;br /&gt;
 /*&lt;br /&gt;
  * This ASM-function returns the CPU index (0 to 3) of the current S698PM CPU.&lt;br /&gt;
  */&lt;br /&gt;
  static inline unsigned int get_asr17(void);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Starting CPUs&lt;br /&gt;
  *&lt;br /&gt;
  * All CPUs have the same entry point.&lt;br /&gt;
  * The linker defaults to 0x40000000.&lt;br /&gt;
  * DMON's ep command is used to set each CPU's initial PC to this.&lt;br /&gt;
  *&lt;br /&gt;
  * This function is entered immediately on entering main().&lt;br /&gt;
  * It determines the index (0 to 3) of the CPU running the code.&lt;br /&gt;
  * If this is the START_CPU_INDEX it initializes the data areas used by all CPUs&lt;br /&gt;
  * and returns to main().&lt;br /&gt;
  * Otherwise, it checks to see if any work is waiting, does it,&lt;br /&gt;
  * and halts the CPU. When work becomes available, the CPU is restarted,&lt;br /&gt;
  * does the work, and halts again. This function never returns if running on&lt;br /&gt;
  * these CPUs.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 int fftCpusStart(void);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Preliminary start of the selected CPUs if other than the one running this.&lt;br /&gt;
  * Each such CPU starts, runs through its initialization code, and powers down&lt;br /&gt;
  * Each CPU shares the same initialization code, so there is a pause between&lt;br /&gt;
  * each startup just in case ...&lt;br /&gt;
  *&lt;br /&gt;
  * A CPU is restarted when there is work for it to do&lt;br /&gt;
  * (restarts are done directly, not by this).&lt;br /&gt;
  *&lt;br /&gt;
  *  Inputs:&lt;br /&gt;
  *  	const int		which cpus		from 0 to 0xf, the current CPU, if selected, is ignored&lt;br /&gt;
  *&lt;br /&gt;
  *  Returns:							None&lt;br /&gt;
  *&lt;br /&gt;
  * 						N.B. This routine should not be used to restart CPUs&lt;br /&gt;
  */&lt;br /&gt;
 void startCpus(const int whichcpus);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * INPUT ARRAY REARRANGEMENT&lt;br /&gt;
  *&lt;br /&gt;
  * This is used with a discrimination in time (DIT) implementation of the FFT.&lt;br /&gt;
  * Separate parts of the rearranged array can be processed independently&lt;br /&gt;
  * on different CPUs without any interaction between the CPUs being required.&lt;br /&gt;
  * The last two stages (4 CPUS) or just the last stage (2 CPUS)can only be done when&lt;br /&gt;
  * the previous stages are finished, and are again distributed across all CPUs.&lt;br /&gt;
  *&lt;br /&gt;
  * The best approach to input rearrangement is to do it as the data arrives.&lt;br /&gt;
  *&lt;br /&gt;
  * Alternatively, by setting a parameter rearrangement can be done in parallel&lt;br /&gt;
  * one each CPU.&lt;br /&gt;
  *&lt;br /&gt;
  * Three very similar functions, not parallel, are given to allow a complete input&lt;br /&gt;
  * array be rearranged:&lt;br /&gt;
  * 	fftArrangeOut		an out of place rearrange, the input array is unchanged&lt;br /&gt;
  * 	fftArrangeIn		an in place rearrange, the input array is rearranged in situ&lt;br /&gt;
  * 	fftaArrangeIndex	creates an array of indexes. Entry [i] gives the index where&lt;br /&gt;
  * 						the (in-phase, quadrature) complex pair should be stored when&lt;br /&gt;
  * 						data is read one pair at a time&lt;br /&gt;
  *						- the input array will then not need further rearrangement&lt;br /&gt;
  *&lt;br /&gt;
  * All three functions assume the array length is a power of 2, and this power is what&lt;br /&gt;
  * is input to give the array length.&lt;br /&gt;
  *&lt;br /&gt;
  * (Thanks for bit-swap method used to graphics.stanford.edu/~seander/bithacks.html#ReverseParallel)&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  *	Out of place rearrangement of input array to prepare for FFT.&lt;br /&gt;
  *	Assumes array length is a power of 2.&lt;br /&gt;
  *&lt;br /&gt;
  *	Inputs:&lt;br /&gt;
  *		fft_cpx* 		cin		pointer to an array of complex numbers&lt;br /&gt;
  *								(the length of this array must be a power of 2)&lt;br /&gt;
  *		int				lenP2	log to base 2 of array length. 0 &amp;lt;= lenP2 &amp;lt;= 30.&lt;br /&gt;
  *&lt;br /&gt;
  *		fft_cpx* 		result	pointer to resulting array of complex numbers&lt;br /&gt;
  *								(same length as cin array)&lt;br /&gt;
  *&lt;br /&gt;
  *	Result:				A rearranged version of cin input array in the result array&lt;br /&gt;
  *&lt;br /&gt;
  *	N.B.				Space for the result array of complex numbers must be allocated&lt;br /&gt;
  *						before calling this function, same length as the cin input array.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 void fftArrangeOut(fft_cpx* cin, fft_cpx* result, int lenP2);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   *	In place rearrangement of input array to prepare for FFT.&lt;br /&gt;
   *	Assumes array length is a power of 2.&lt;br /&gt;
   *&lt;br /&gt;
   *	Inputs:&lt;br /&gt;
   *		fft_cpx* 		cin		pointer to an array of complex numbers&lt;br /&gt;
   *								(the length of this array must be a power of 2)&lt;br /&gt;
   *		int				lenP2	log to base 2 of array length.&lt;br /&gt;
   *&lt;br /&gt;
   *	Result:				A rearranged version of cin input array in the same space&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void fftArrangeIn(fft_cpx* x, int lenP2);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   *	Generate an array of indices giving the array position where each successive input&lt;br /&gt;
   *	should be placed in the input array.&lt;br /&gt;
   *	This array could be stored in ROM and used when inputting data so as to avoid&lt;br /&gt;
   *	any subsequent need to spend time rearranging the input array.&lt;br /&gt;
   *&lt;br /&gt;
   *	Assumes amount of input datais a power of 2.&lt;br /&gt;
   *&lt;br /&gt;
   *	Inputs:&lt;br /&gt;
   *		int * 			mapindex	pointer to an array of ints that will hold the index to be used&lt;br /&gt;
   *									in the complex input array for each successive data input.&lt;br /&gt;
   *									(the length of this array must be a power of 2&lt;br /&gt;
   *		int				lenP2		log to base 2 of array length. 0 &amp;lt;= lenP2 &amp;lt;= 30&lt;br /&gt;
   *									(regarding the array as an array of complex numbers)&lt;br /&gt;
   *&lt;br /&gt;
   *	Result:				mapindex will hold appropriate index in data array to use to hold complex input i&lt;br /&gt;
   *&lt;br /&gt;
   *	N.B. if the input data is an array of scalars, the length of mapindex[] will be half of the length&lt;br /&gt;
   *		 of the array to hold the scalars, and the input index k used to look up the mapindex array should only&lt;br /&gt;
   *	     increment after each pair of reals have been added to dataarray[mapindex[k]&amp;lt;&amp;lt; 1] and dataarray[(mapindex[k]&amp;lt;&amp;lt; 1) +1]&lt;br /&gt;
   *	     (they will be treated as the real and imaginary parts of the complex number at the index given by mapindex[k])&lt;br /&gt;
   *&lt;br /&gt;
   *	N.B. Space for the mapindex array of ints must be allocated before calling this function,&lt;br /&gt;
   *		 same length as complex data input array, half length of real data input arrays.&lt;br /&gt;
   *&lt;br /&gt;
   *	N.B. The mapping array is its own inverse&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void fftArrangeIndex(int* mapindex, int lenP2);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
    *	If the 'realonly' option is selected, the input data is treated as having in-phase components only&lt;br /&gt;
    *	and any quadrature component is ignored and will be overwritten in processing.&lt;br /&gt;
    *	The 'real', i.e. in-phase input components are rearranged into half the number of inputs&lt;br /&gt;
    *	with every second in-phase input now in the quadrature position, and zero in remaining half of the input array.&lt;br /&gt;
    *	This allows faster FFT processing but requires post-processing.&lt;br /&gt;
    *	(Post processing is distributed across all processors and done later in a final processing phase.&lt;br /&gt;
    *	 It produces the positive frequency components only, the negative components can be obtained by taking&lt;br /&gt;
    *	 the complex conjugates of these.)&lt;br /&gt;
    *&lt;br /&gt;
    *	Assumes amount of input data is a power of 2.&lt;br /&gt;
    *&lt;br /&gt;
    *	Inputs:&lt;br /&gt;
    *		fft_cpx * 		cin			input array with all 0s in quadrature (imaginary) positions.&lt;br /&gt;
    *									Altered so that quadrature positions hold alternate real inputs,&lt;br /&gt;
    *									and remaining array entries are made (0.0,0.0)&lt;br /&gt;
    *		int				lenP2		log to base 2 of array length. 0 &amp;lt;= lenP2 &amp;lt;= 30.&lt;br /&gt;
    *									(regarding the array as an array of complex numbers)&lt;br /&gt;
    *&lt;br /&gt;
    *	Result:				first half of cin holds rearranged data, rest is (0.0,0.0)&lt;br /&gt;
    *&lt;br /&gt;
    *						N.B. 		use of this function can usually be avoided by simply casting an input&lt;br /&gt;
    *									array of scalars to be an array of complex numbers.&lt;br /&gt;
    */&lt;br /&gt;
  void fftRealOnlyArrange(fft_cpx * cin, const int lenP2);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * TWIDDLES ARRAY&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * For an input data array of length N the 'twiddle' factors are the N complex roots&lt;br /&gt;
   * of unity. Only N/2 of these are calculated, as the others are just minus these,&lt;br /&gt;
   * and are provided by using subtraction rather than addition.&lt;br /&gt;
   *&lt;br /&gt;
   * Getting the complex roots of unity is time consuming, so where the size of&lt;br /&gt;
   * array to be processed is known in advance the twiddles array should be stored&lt;br /&gt;
   * in ROM. Two arrays should be stored, one for the forward FFT, one for the inverse.&lt;br /&gt;
   * Each has length N/2, half that of the complex data array.&lt;br /&gt;
   *&lt;br /&gt;
   * Time consuming calculations of sines and cosines are involved, but in some cases&lt;br /&gt;
   * can be avoided by exploiting various symmetries. These require the complex data array&lt;br /&gt;
   * size to be at least 8, but it is restricted here to at least 1 &amp;lt;&amp;lt; FFT_MIN_LENP2, or 32 at present.&lt;br /&gt;
   *&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *		fft_cpx* 		twiddles	pointer to an array of complex numbers&lt;br /&gt;
   *									(the length of this array will be half the length&lt;br /&gt;
   *									 of the complex data array with which the twiddles&lt;br /&gt;
   *									 array will be used)&lt;br /&gt;
   *		const int		lenP2		log to base 2 of complex data array length.&lt;br /&gt;
   *									(from FFT_MIN_LENP2	to FFT_MAX_LENP2, i.e. 5 to	17)&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		type 		0 for FFT, 1 for inverse FFT&lt;br /&gt;
   *&lt;br /&gt;
   * Result:				N/2 of the N complex roots of unity in twiddles array&lt;br /&gt;
   *&lt;br /&gt;
   * N.B.				Space for the twiddles array of N/2 complex numbers must be allocated&lt;br /&gt;
   *						before calling this function, where N is the length of the complex data&lt;br /&gt;
   *						array. i.e. 1 &amp;lt;&amp;lt; lenP2.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void fillTwiddles(fft_cpx* twiddles, const int lenP2, const int type);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * FFT PROCESSING&lt;br /&gt;
   *&lt;br /&gt;
   * The (in-phase, quadrature) input data is regarded as an array of complex numbers.&lt;br /&gt;
   * The resulting FFT is also an array of complex numbers.&lt;br /&gt;
   *&lt;br /&gt;
   * If the data is not already in rearranged order, by setting the 'arrange' parameter&lt;br /&gt;
   * the input array can be rearranged in parallel, with each CPU doing its own section.&lt;br /&gt;
   * This involves copying the original input data into the area at FFT_RAIN,&lt;br /&gt;
   * where it will eventually be overwritten by the FFT result, with the original&lt;br /&gt;
   * input data left unchanged.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * This function calculates all or part of the FFT.&lt;br /&gt;
   * It can be used on separate processors or in separate threads.&lt;br /&gt;
   *&lt;br /&gt;
   * It processes part or all of a complex data array, replacing parts of the&lt;br /&gt;
   * array with appropriate FFT data. After any initial rearrangement&lt;br /&gt;
   * all processing is done in situ .&lt;br /&gt;
   *&lt;br /&gt;
   * The length of a sub-array must be a power of 2 and no less than 8.&lt;br /&gt;
   * The sub-array can be the whole array.&lt;br /&gt;
   *&lt;br /&gt;
   * The size of the butterfly blocks with which to start processing a sub-array is&lt;br /&gt;
   * input as a power of 2.&lt;br /&gt;
   *&lt;br /&gt;
   * Where the blocks in the subarray have not already been processed,&lt;br /&gt;
   * the starting power of 2 is 1.&lt;br /&gt;
   *&lt;br /&gt;
   * If parts of a subarray have already been processed, the correct butterfly&lt;br /&gt;
   * step must be given. All parts of the subarray must have the same size.&lt;br /&gt;
   *&lt;br /&gt;
   * The post-processing phrase needed when the original data is in-phase only&lt;br /&gt;
   * is done if 'secondpass' is set.&lt;br /&gt;
   *&lt;br /&gt;
   * Rearrangement of the data for this section is done if the 'arrange' is set.&lt;br /&gt;
   *&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *		fft_cpx* 		arranged	pointer to the array of complex numbers that&lt;br /&gt;
   *									initially contains the rearranged complex data input.&lt;br /&gt;
   *									Will hold result.&lt;br /&gt;
   *		const int		lenP2		Power of 2 that gives length of input array.&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		start		position in array at which sub-array starts&lt;br /&gt;
   *		const int		nextstart	position one after end of data to process&lt;br /&gt;
   *									N.B. (nextstart - start) must be a power of 2&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		oddadd		Added internally to half of sub-array size.&lt;br /&gt;
   *									Used to get distance from even to odd entries.&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		startP2		power of 2 that gives butterfly at which to start.&lt;br /&gt;
   *									Must be at least 1.&lt;br /&gt;
   *									1 if no previous processing done on this sub-array.&lt;br /&gt;
   *									Otherwise gives size of butterfly to start with.&lt;br /&gt;
   *&lt;br /&gt;
   *		const fft_cpx*	twiddles	pointer to twiddles array - this must correspond&lt;br /&gt;
   *									to the original complete complex input array.&lt;br /&gt;
   *		const int		toffset		initial offset into twiddles array&lt;br /&gt;
   *		const int		twinc		initial increment to using going through twiddles array&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		normalise	0 for don't normalize, anything else -&amp;gt; normalize&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		arrange		0 for don't arrange, anything else -&amp;gt; arrange&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		realonly	0 if original data complex, 1 if in-phase only&lt;br /&gt;
   *									and has been rearranged&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		secondpass	0 if not ready to do post-processing,&lt;br /&gt;
   *									1 to do post-processing only&lt;br /&gt;
   *&lt;br /&gt;
   * Result:				FFT processed values in situ in this subarray&lt;br /&gt;
   *&lt;br /&gt;
   *	N.B.				If 'realonly' is selected, assumes that the input array is a compressed&lt;br /&gt;
   *						version of something twice as long, and that this additional space&lt;br /&gt;
   *						is available.&lt;br /&gt;
   *&lt;br /&gt;
   *	N.B.				If 'realonly' is selected, FFT result contains the positive frequencies&lt;br /&gt;
   *						only. Negative frequencies are easily derived if needed as the complex&lt;br /&gt;
   *						conjugates of these.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void fftProc(fft_cpx* arranged, const int lenP2,&lt;br /&gt;
  			 const int start, const int nextstart,&lt;br /&gt;
  			 const int oddadd, const int startP2,&lt;br /&gt;
      		 const fft_cpx* twiddles,&lt;br /&gt;
      		 const int toffset, const int twinc,&lt;br /&gt;
      		 const int normalise, const int arrange,&lt;br /&gt;
      		 const int realonly, const int secondpass);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Allocates work of doing FFT to one or more CPUs&lt;br /&gt;
   * and combines results from them to give FFT.&lt;br /&gt;
   *&lt;br /&gt;
   * The input is an array of complex numbers representing the&lt;br /&gt;
   * (in-phase,quadrature) data.&lt;br /&gt;
   * Its length must be a power of 2 - this power rather than the&lt;br /&gt;
   * length is input.&lt;br /&gt;
   *&lt;br /&gt;
   * The complex number array giving the FFT is returned in situ&lt;br /&gt;
   * in the input array, unless the 'arrange parameter is set,&lt;br /&gt;
   * in which case the result is in the area at FFT_RAIN.&lt;br /&gt;
   *&lt;br /&gt;
   * At present the number of CPUs to use must be 1, 2 or 4.&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *		fft_cpx* 		arranged	pointer to an array of complex numbers that&lt;br /&gt;
   *									holds the rearranged complex data input.&lt;br /&gt;
   *									Will hold result.&lt;br /&gt;
   *		const int		lenP2		power of 2 that gives size of array&lt;br /&gt;
   *&lt;br /&gt;
   *		const fft_cpx*	twiddles	pointer to twiddles array&lt;br /&gt;
   *									- this must correspond to input array&lt;br /&gt;
   *									  (it will be half its size)&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		whichcpus	1 to 0xf, which CPUs to use (binary xxxx, x=1 for use)&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		normalise	0 for don't normalize, anything else -&amp;gt; normalize&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		arrange		0 for don't arrange, anything else -&amp;gt; arrange&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		realonly	0 if original data has both components, 1 if in-phase only&lt;br /&gt;
   *									and has been rearranged&lt;br /&gt;
   *&lt;br /&gt;
   * Result:				Complex valued FFT in situ in arranged&lt;br /&gt;
   *&lt;br /&gt;
   * N.B.				Assumes START_CPU_INDEX is 0&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void fftMulti(fft_cpx* cin, const int lenP2,&lt;br /&gt;
  			  const fft_cpx* twiddles,&lt;br /&gt;
      		  const int whichcpus,&lt;br /&gt;
      		  const int normalise,&lt;br /&gt;
      		  const int arrange,&lt;br /&gt;
      		  const int realonly);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Gives one part of the FFT calculation to the selected CPU for execution.&lt;br /&gt;
   *&lt;br /&gt;
   * The input is part of an array of complex numbers.&lt;br /&gt;
   * Its length must be a power of 2 - this power rather than the&lt;br /&gt;
   * length is input.&lt;br /&gt;
   *&lt;br /&gt;
   * The output is placed in the appropriate locations in the input array,&lt;br /&gt;
   * unless the 'arrange' parameter is set, in which case the output is&lt;br /&gt;
   * in the area at FFT_RAIN.&lt;br /&gt;
   *&lt;br /&gt;
   * At present the identifier of the CPU to use must be 1, 2, 4 or 8, anything&lt;br /&gt;
   * else the function returns without doing anything.&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *		const int		which		which CPU to use - must be 1, 2, 4 or 8&lt;br /&gt;
   *&lt;br /&gt;
   *		fft_cpx* 		arranged	pointer to an array of complex numbers that&lt;br /&gt;
   *									holds the rearranged complex data input.&lt;br /&gt;
   *									Will hold result.&lt;br /&gt;
   *		const int		lenP2		power of 2 that gives size of array&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		begin		index into arranged, location where this processing is to start&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		nextbegin	index into arranged, begin &amp;lt;= index &amp;lt; nextbegin&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		oddadd		Added internally to half of sub-array size.&lt;br /&gt;
   *									Used to get distance from even to odd entries.&lt;br /&gt;
   * 	const int		startP2		1 &amp;lt;&amp;lt; (lenP2 - startP2) gives initial step size in twiddles array&lt;br /&gt;
   *&lt;br /&gt;
   *		const fft_cpx*	twiddles	pointer to twiddles array&lt;br /&gt;
   *									- this must correspond to input array&lt;br /&gt;
   *									  (it will be half its size)&lt;br /&gt;
   *&lt;br /&gt;
   *  	const int		toffset		initial offset into twiddles array&lt;br /&gt;
   *		const int		twinc		initial increment to using going through twiddles array&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		normalise	0 for don't normalize, anything else -&amp;gt; normalize&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		arrange		0 for don't arrange, anything else -&amp;gt; arrange&lt;br /&gt;
   *&lt;br /&gt;
   * 	const int		realonly	0 if original data complex, 1 if in-phase only&lt;br /&gt;
   *									and has been rearranged&lt;br /&gt;
   *&lt;br /&gt;
   * Result:				Updated complex values for this stage of FFT processing in arranged&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void giveToCpu(const int which,							// 1,2,4 or 8&lt;br /&gt;
  			   fft_cpx* cin, const int lenP2,				// input array&lt;br /&gt;
  			   const int begin, const int nextbegin,		// part indices&lt;br /&gt;
  			   const int oddadd, const int startP2,&lt;br /&gt;
  			   const fft_cpx* twiddles,&lt;br /&gt;
  			   const int toffset, const int twinc,&lt;br /&gt;
  			   const int normalise, const int arrange,&lt;br /&gt;
  			   const int realonly, const int secondpass);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Wait for selected CPUs to have finished.&lt;br /&gt;
   * Returns when no CPU has work pending.&lt;br /&gt;
   * Can wait indefinitely. TODO put in a time check&lt;br /&gt;
   *&lt;br /&gt;
   * All stages of the FFT except at most the last two (for the S698PM) proceed independently&lt;br /&gt;
   * with no need for communication between CPUs.&lt;br /&gt;
   *&lt;br /&gt;
   * If using 4 CPUs, each of the last two stages must wait for all CPUs to have finished&lt;br /&gt;
   * the preceding stage.&lt;br /&gt;
   *&lt;br /&gt;
   * If using 2 CPUs, they must wait to process the last stage until both CPUs have finished&lt;br /&gt;
   * the earlier stages.&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *		const int		whichcpus	which CPUs to check - xxxx, 1 to check, 0 not to check&lt;br /&gt;
   *&lt;br /&gt;
   *&lt;br /&gt;
   * Result:				Wait, only return when no selected CPU has work pending&lt;br /&gt;
   */&lt;br /&gt;
  void fftWait();&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * UTILITIES&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Get the number of CPUs enabled by the selections in whichcpus.&lt;br /&gt;
   *&lt;br /&gt;
   * 	Input:&lt;br /&gt;
   * 		const int 	whichcpus	0 to 0xf  (binary xxxx, 1 = use CPU&lt;br /&gt;
   *&lt;br /&gt;
   * 	Output:&lt;br /&gt;
   * 		int			Count of currently selected CPUs ( 0 to 4)&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  int getNumCpus(const int whichcpus);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Validate the input settings and correct if possible&lt;br /&gt;
   *&lt;br /&gt;
   *	Inputs:&lt;br /&gt;
   *		const int		lenP2			must be from FFT_MIN_LENP2	to FFT_MAX_LENP2, (i.e. 5 to 17)&lt;br /&gt;
   *&lt;br /&gt;
   *		int *			cpusrequest		should be from 0 to 0xf, corresponding to 1, 2 or 4 cpus (but not 3)&lt;br /&gt;
   *										(correction attempt made if three CPUs chosen)&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		numruns			no validation&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		type			must be 0 or 1&lt;br /&gt;
   *&lt;br /&gt;
   *		int *			lines			corrected to 1 &amp;lt;&amp;lt; lenP2 if greater than this&lt;br /&gt;
   *&lt;br /&gt;
   *	Returns:&lt;br /&gt;
   *		int				0 if all o.k., 1 if a problem (messages given),&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  int settingsIncorrect(const int lenP2, int *cpusrequest, const int numruns, const int type, int* lines);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
   * Display an array of complex numbers on the console.&lt;br /&gt;
   * Can be used to display data input or FFT result.&lt;br /&gt;
   *&lt;br /&gt;
   * N.B. At present assumes floats being used&lt;br /&gt;
   *&lt;br /&gt;
   * Inputs:&lt;br /&gt;
   * 	fft_cpx* 		in			input array of complex numbers&lt;br /&gt;
   *&lt;br /&gt;
   *		const int		length		length of the array&lt;br /&gt;
   *&lt;br /&gt;
   *		const double	tolerance	absolute values less than this are shown as 0.0&lt;br /&gt;
   *&lt;br /&gt;
   *	Result:				Array is output to the console&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  void showC(const fft_cpx* in, const int length, const double tolerance);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  /*&lt;br /&gt;
    * Display main parts of FFT result on the console.&lt;br /&gt;
    * Shows initial 8 positive frequency components including 0 component,&lt;br /&gt;
    * show 8 components before Nyquist frequency, 8 components from Nyquist,&lt;br /&gt;
    * and last 8 components.&lt;br /&gt;
    * If 'realonly' is selected, shows result up to Nyquist frequency only.&lt;br /&gt;
    *&lt;br /&gt;
    * N.B. At present assumes floats being used&lt;br /&gt;
    *&lt;br /&gt;
    * Inputs:&lt;br /&gt;
    * 		fft_cpx* 		in			input array of complex numbers&lt;br /&gt;
    *&lt;br /&gt;
    *		const int		length		length of the array&lt;br /&gt;
    *&lt;br /&gt;
    *		const double	tolerance	absolute values less than this are shown as 0.0&lt;br /&gt;
    *&lt;br /&gt;
    *		const int 		realonly	0 to show full FFT, 1 to show non-negative frequencies only.&lt;br /&gt;
    *&lt;br /&gt;
    *	Result:				Array is output to the console&lt;br /&gt;
    *&lt;br /&gt;
    */&lt;br /&gt;
  void show8C(const fft_cpx* in, const int length, const double tolerance, const int realonly);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 #endif // FFT_H_&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:backup]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Bkavanagh</name></author>
	</entry>
</feed>