📄 ffttestc.c
字号:
/**** 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 + -