⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffttestc.c

📁 ARM库里的FFT算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/**** PerformFFT ********************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * perform either a forward or inverse FFT on the data given using either ARM or C
 * routines giving the user choices for windowing (if complex) and performing 
 * the FFT in place or out of place (if using the ARM routines)
 *
 * Inputs
 * ------
 *   inputs
 *   - an array of complex data to be FFT'd
 *   nInputs
 *   - the number of complex data points in the array inputs
 *   arm
 *   - TRUE  : use ARM Assembler routines to perform FFT (has in place option)
 *     FALSE : use C routines to perform FFT (no in place option)
 *   forward
 *   - TRUE  : forward FFT the given data
 *     FALSE : inverse FFT the given data
 *   real
 *   - TRUE  : the complex data is actually all real (zero imaginary part) and
 *             the real routines will be used
 *             forward must be TRUE else will abort
 *     FALSE : the complex data really is complex and complex routines are used
 * Return Values
 * ------ ------
 *     Complex * - an array of nInputs complex data points result of FFT
 *     NULL      - some error occurred (memory allocation?)
 *
 * Memory allocated (not deallocated)
 * ------ ---------  --- -----
 * the returned Complex array
 * deallocate after use
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Complex *PerformFFT( Complex inputs[ ], unsigned int nInputs, Boolean arm, Boolean forward, Boolean real )
{
	int				*inputsInt = NULL ;
	Complex			*windowInputs = NULL ;
	Complex			*outputs ;
	unsigned int	outCounter ;
	void			*inputID ;
	Complex			*outputID ;
	Boolean			inPlace ;
	
	if( ( !inputs ) || ( !forward && real ) ) {
		fprintf( stderr, "[PerformFFT] Error in arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
		return NULL ;
	}
	
	if( ( outputs = ( Complex * )calloc( nInputs, sizeof( Complex ) ) ) == NULL ) {
		fprintf( stderr, "Failure to create array for output data, aborting.\n\n" ) ;
		return NULL ;
	}
	
	inputID = inputs ;
	if( ( forward ) && ( !real ) ) {
		if( ( windowInputs = Window( inputs, nInputs ) ) != NULL ) {
			inputID = windowInputs ;
		}
	}
	
	if( real ) {
		if( ( inputsInt = CreateIntFromComplex( inputs, &nInputs ) ) == NULL ) {
			fprintf( stderr, "Failure to create array for FFT, aborting.\n\n" ) ;
			free( ( void * ) outputs ) ;
			return NULL ;
		}
		inputID = inputsInt ;
	}
	
	printf( "Calculating the " ) ;
	if( real ) {
		printf( "real " ) ;
	}
	if( forward ) {
		printf( "forward FFT " ) ;
	}
	else {
		printf( "inverse FFT " ) ;
	}
	if( arm ) { 
		printf( "(ARM-based)" ) ; 
	} 
	else { 
		printf( "(C-based)" ) ; 
	}
	printf( "...\n\n" ) ;

	if( arm ) {
		inputID = inputs ;
		outputID = outputs ;
		if( real ) {
			inputID = inputsInt ;
			nInputs /= 2 ;
			inPlace = FALSE ;
		}
		else if( ( inPlace = IsInPlace( ) ) == TRUE ) {
			outputID = inputs ;
		}
		
		if( !PerformARMFFTs( outputID, inputID, nInputs, forward, real ) ) {
			free( ( void * ) outputs ) ;
			outputs = NULL ;
		}
		else if( inPlace ) {
			for( outCounter = 0 ; outCounter < nInputs; outCounter += 1 ) {
				outputs[ outCounter ].r = inputs[ outCounter ].r ;
				outputs[ outCounter ].i = inputs[ outCounter ].i ;
			}
		}
	}
	else {
		inputID = inputs ;
		if( real ) {
			inputID = inputsInt ;
		}
		
		if( !PerformCFFTs( outputs, inputID, nInputs, forward, real ) ) {
			free( ( void * ) outputs ) ;
			outputs = NULL ;
		}
	}
	
	if( real ) {
		free( ( void * ) inputsInt ) ;
	}
	else if( windowInputs != NULL ) {
		free( ( void * ) windowInputs ) ;
	}

	if( outputs != NULL ) {
		if( real ) {
			printf( "Real " ) ;
		}
		printf( "FFT calculated.\n\n" ) ;
	}

	return outputs ;
}

/**** SaveComplexData ***************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * get the file name from the user and open the file for writing in normal mode, 
 * remove the sign extension from the data, write the complex data as integers 
 * (interleaved real and imaginary parts) and close the file
 *
 * Inputs
 * ------
 *   dataComplex
 *   - an array of complex data to write to the file
 *   size
 *   - the number of complex data points in the array passed
 *   dataType
 *   - an optional string that defines the data that is to written out
 *     displayed to the user during file selection time
 *     pass NULL if non-specific data is to be written
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static void SaveComplexData( Complex dataComplex[ ], unsigned int size, char *dataType )
{
	int		*dataInt ;

	if( ( dataInt = CreateIntFromComplex( dataComplex, &size ) ) == NULL ) {
		return ;
	}
	
	REMOVESIGNEXTENDARRAY( dataInt, size, 16 ) ;
	
	SaveData( dataInt, size, WORDBYTES, 0, dataType ) ;
	
	free( ( void * ) dataInt ) ;
}

/**** Transform *********************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * perform the coding from reading the users data in to performing the forward FFT,
 * inverse FFT or both forward FFT immediately followed by the inverse FFT, 
 * and write the data back to a users file
 *
 * all files are given by the user during the operations at run time
 *
 * Inputs
 * ------
 *   option
 *   - the coding option being performed : when to use ARM or C routines and if
 *     inverting immediately
 * Return Values
 * ------ ------
 *     TRUE  - the coding operation and all file operations were successful
 *     FALSE - some error occurred, operations failed
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Boolean Transform( unsigned int option )
{
	Complex			*inputs ;
	unsigned int	nInputs ;
	unsigned int	is2 ;
	Complex			*outputs = NULL ;
	Boolean			arm ;
	Boolean			forward ;
	Boolean			real ;
	
	printf( "Perform Fast Fourier Transform...\n\n" ) ;
	
	if( ( inputs = GetComplexData( "input", &nInputs ) ) == NULL ) {
		return FALSE ;
	}
	
	ISPOWEROF2( nInputs, is2 ) ;
	if( !is2 ) {
		printf( "The number of inputs to the FFT must a multiple of 2 (given '%d'), aborting.\n\n", nInputs ) ;
		free( ( void * ) inputs ) ;
		return FALSE ;
	}
	
	switch( option ) {
		case  1 :
			arm = TRUE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  2 :
			arm = FALSE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  3 :
			arm = TRUE ;
			forward = FALSE ;
			real = FALSE ;
			break ;
		case  4 :
			arm = FALSE ;
			forward = FALSE ;
			real = FALSE ;
			break ;
		case  5 :
			arm = TRUE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  6 :
			arm = FALSE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  7 :
			arm = TRUE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  8 :
			arm = FALSE ;
			forward = TRUE ;
			real = FALSE ;
			break ;
		case  9 :
			arm = TRUE ;
			forward = TRUE ;
			real = TRUE ;
			break ;
		case 10 :
			arm = FALSE ;
			forward = TRUE ;
			real = TRUE ;
			break ;
		default :
			free( ( void * ) inputs ) ;
			return FALSE ;
	}

	if( ( option == 9 ) || ( option == 10 ) ) {
		printf( "Number of inputs to FFT is '%d'\n\n", nInputs*2 ) ;
	}
	else {
		printf( "Number of inputs to FFT is '%d'\n\n", nInputs ) ;
	}
	
	outputs = PerformFFT( inputs, nInputs, arm, forward, real ) ;
	free( ( void * ) inputs ) ;
	if( !outputs ) {
		return FALSE ;
	}
	
	if( ( option >= 5 ) && ( option <= 8 ) ) {
		switch( option ) {
			case 5 :
				arm = TRUE ;
				forward = FALSE ;
				real = FALSE ;
				break ;
			case 6 :
				arm = FALSE ;
				forward = FALSE ;
				real = FALSE ;
				break ;
			case 7 :
				arm = FALSE ;
				forward = FALSE ;
				real = FALSE ;
				break ;
			case 8 :
				arm = TRUE ;
				forward = FALSE ;
				real = FALSE ;
				break ;
		}
		inputs = PerformFFT( outputs, nInputs, arm, forward, real ) ;
	}
	
	switch( option ) {
		case  1 :
		case  2 :
		case  3 :
		case  4 :
		case  9 :
		case 10 :
			SaveComplexData( outputs, nInputs, "output" ) ;
			free( ( void * ) outputs ) ;
			break ;
		case  5 :
		case  6 :
		case  7 :
		case  8 :
			if( !inputs ) {
				return FALSE ;
			}
			SaveComplexData( inputs, nInputs, "fully transformed" ) ;
			free( ( void * ) inputs ) ;
			break ;
		default :
			break ;
	}
	
	return TRUE ;
}

/**** Window ************************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * determine from the user whether windowing should be done, and if so whether the
 * windowing is Hamming or Hanning
 *
 * if windowing is required, perform the window on the given data and return the
 * windowed data
 *
 * if no windowing is required NULL is returned
 *
 * Inputs
 * ------
 *   inputs
 *   - a complex array containing the data before FFT performed that may have a
 *     window applied to it
 *   nInputs
 *   - the number of complex data points in the array inputs
 * Return Values
 * ------ ------
 *     Complex * - the complex data after a window has been applied
 *     NULL      - no window was required by the user or some error occurred
 *                 (no test for error possible, just assume no window)
 *
 * Memory allocated (not deallocated)
 * ------ ---------  --- -----
 * the return Complex array, if not NULL
 * deallocate after use
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Complex *Window( Complex inputs[ ], unsigned int nInputs )
{
	Complex			*windowInputs = NULL ;
	unsigned int	window ;
	int				*inputsInt ;
	
	if( !inputs ) {
		fprintf( stderr, "[Window] Error in arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
		return NULL ;
	}
	
	switch( window = HasWindow( ) ) {
		case 0 :
			printf( "No windowing will be performed.\n\n" ) ;
			break ;
		case 1 :
		case 2 :
			if( ( inputsInt = CreateIntFromComplex( inputs, &nInputs ) ) == NULL ) {
				fprintf( stderr, "Failure to create array for windowing.\n" ) ;
				fprintf( stderr, "Unable to perform windowing, aborting.\n\n" ) ;
				break ;
			}
			
			if( window == 1 ) {
				printf( "FFT with Hamming Window.\n\n" ) ;
				HammingWindow( inputsInt, inputsInt, nInputs ) ;
			}
			else {
				printf( "FFT with Hanning Window.\n\n" ) ;
				HanningWindow( inputsInt, inputsInt, nInputs ) ;
			}
			
			windowInputs = CreateComplexFromInt( inputsInt, &nInputs ) ;
			free( ( void * ) inputsInt ) ;
			if( !windowInputs ) {
				fprintf( stderr, "Failure to create array for windowing.\n" ) ;
				fprintf( stderr, "Unable to perform windowing, aborting.\n\n" ) ;
			}
			break ;
		default :
			printf( "That was not a valid choice, no windowing will be performed.\n\n" ) ;
			break ;
	}
	
	return windowInputs ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -