home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Phoenix Heaven Sunny 2
/
APPARE2.BIN
/
oh_towns
/
tetujin
/
src.lzh
/
FFT.C
next >
Wrap
Text File
|
1995-01-05
|
4KB
|
193 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "fft.h"
#define NOERR 0
static siftFlg = 1 ; /* DC成分の位置 0 シフトしない 1 シフトする */
static double *sinTable ;
static double *cosTable ;
static double *subBuf ;
static tableFlg = 1 ; /* 0のときはテーブルを作成しない */
int fft_2( char *work, double real[], double imag[], int ex, int inv )
{
int i, length ;
length = 1 << ex ;
makeTable( work, length, inv ) ;
tableFlg = 0 ;
for( i=0 ; i<length ; i++ )
{
if( inv == -1 )
sift( &real[i*length], &imag[i*length], length ) ;
fft_1( work, &real[i*length], &imag[i*length], ex, inv ) ;
if( inv == 1 )
sift( &real[i*length], &imag[i*length], length ) ;
}
matrixReverce( real, length ) ;
matrixReverce( imag, length ) ;
for( i=0 ; i<length ; i++ )
{
if( inv == -1 )
sift( &real[i*length], &imag[i*length], length ) ;
fft_1( work, &real[i*length], &imag[i*length], ex, inv ) ;
if( inv == 1 )
sift( &real[i*length], &imag[i*length], length ) ;
}
matrixReverce( real, length ) ;
matrixReverce( imag, length ) ;
tableFlg = 1 ;
return NOERR ;
}
static int sift( double real[], double imag[], int length )
{
int i ;
double temp ;
if( siftFlg == 0 )return NOERR ;
for( i=0 ; i<(length >> 1) ; i++ )
{
temp = real[i] ;
real[i] = real[ i + (length >> 1) ] ;
real[ i + (length >> 1) ] = temp ;
temp = imag[i] ;
imag[i] = imag[ i + (length >> 1) ] ;
imag[ i + (length >> 1) ] = temp ;
}
return NOERR ;
}
static int matrixReverce( double a[], int length )
{
int i, j ;
double temp ;
for( i=0 ; i<length ; i++ )
{
for( j=0 ; j<length ; j++ )
{
if( i < j )
{
temp = a[ j + i*length ] ;
a[ j + i*length ] = a[ i + j*length ] ;
a[ i + j*length ] = temp ;
}
}
}
return NOERR ;
}
int fft_1( char *work, double real[], double imag[], int ex, int inv )
{
int i, j, k, w, j1, j2 ;
int length, length2, count, temp ;
double ar, ai, br, bi, nrml ;
length = 1 << ex ;
if( tableFlg )makeTable( work, length, inv ) ;
count = 1 ;
length2 = length ;
for( i=0 ; i<ex ; i++ )
{
length2 >>= 1 ;
temp = 0 ;
for( j=0 ; j<count ; j++ )
{
w = 0 ;
for( k=0 ; k<length2 ; k++ )
{
j1 = temp + k ;
j2 = j1 + length2 ;
ar = real[j1] ;
ai = imag[j1] ;
br = real[j2] ;
bi = imag[j2] ;
real[j1] = ar + br ;
imag[j1] = ai + bi ;
ar = ar - br ;
ai = ai - bi ;
real[j2] = ar*cosTable[w] - ai*sinTable[w] ;
imag[j2] = ar*sinTable[w] + ai*cosTable[w] ;
w += count ;
}
temp += (2*length2) ;
}
count <<= 1 ;
}
bitReverce( subBuf, real, ex ) ;
bitReverce( subBuf, imag, ex ) ;
nrml = 1.0 / sqrt( (double)length ) ;
for( i=0 ; i<length ; i++ )
{
real[i] *= nrml ;
imag[i] *= nrml ;
}
return NOERR ;
}
static int makeTable( char *work, int length, int inv )
{
int i ;
sinTable = (double *)work ;
cosTable = sinTable + length ;
subBuf = cosTable + length ;
if( inv == 1 )
{
for( i=0 ; i<length ; i++ )
{
sinTable[i] = sin( -_PI * 2 * i / length ) ;
cosTable[i] = cos( -_PI * 2 * i / length ) ;
}
}
else
{
for( i=0 ; i<length ; i++ )
{
sinTable[i] = sin( _PI * 2 * i / length ) ;
cosTable[i] = cos( _PI * 2 * i / length ) ;
}
}
return NOERR ;
}
static bitReverce( double *buf, double a[], int ex )
{
int i, j, bit, length ;
length = 1 << ex ;
for( i=0 ; i<length ; i++ )
{
bit = 0 ;
for( j=0 ; j<ex ; j++ )
{
if( i & (1 << j) )
{
bit |= (1 << (ex - j - 1)) ;
}
}
buf[i] = a[bit] ;
}
for( i=0 ; i<length ; i++ )a[i] = buf[i] ;
return NOERR ;
}