public final class FFT {
public int logm;
final int MAXLOGM = 20; /* max FFT length 2^MAXLOGM */
final double TWOPI = 6.28318530717958647692;
final double SQHALF = 0.707106781186547524401;
int brseed[] = new int[4048];
float tab[][];
public FFT(int nlength) {
double dtemp = Math.log(nlength) / Math.log(2);
if ((dtemp - (int) dtemp) != 0.0) {
throw new Error("FFT length must be a power of 2.");
} else {
this.logm = (int) dtemp;
}
if (logm >= 4) {
creattab(logm);
}
}
/**
* Calculates the magnitude spectrum of a real signal. The returned vector
* contains only the positive frequencies.
*/
public float[] calculateFFTMagnitude(float x[]) {
int i, n;
n = 1 << this.logm;
if (x.length > n) {
throw new Error("Tried to use a " + n
+ "-points FFT for a vector with " + x.length + " samples!");
}
rsfft(x);
float[] mag = new float[n / 2 + 1];
mag[0] = x[0]; // DC frequency must be positive always
if (n == 1) {
return mag;
}
mag[n / 2] = (float) Math.abs(x[n / 2]); // pi (meaning: fs / 2)
// System.out.println("FFT before magnitude");
// IO.DisplayVector(x);
for (i = 1; i < n / 2; i++) {
mag[i] = (float) Math.sqrt(x[i] * x[i] + x[n - i] * x[n - i]);
// System.out.println(mag[i] + " " + x[i] + " " + x[n-i]);
}
// IO.DisplayVector(mag);
return mag;
}
/**
* Calculates the magnitude spectrum of a real signal. The returned vector
* contains only the positive frequencies.
*/
public double[] calculateFFTMagnitude(double inputData[]) {
int i, n;
n = 1 << this.logm;
if (inputData.length > n) {
throw new Error("Tried to use a " + n
+ "-points FFT for a vector with " + inputData.length
+ " samples!");
}
// System.out.println("magnitude test");
// double[] dtest = DSP.DFTMagnitude(inputData);
// IO.DisplayVector(dtest);
float[] x = new float[n];
for (i = 0; i < inputData.length; i++) {
x[i] = (float) inputData[i];
}
rsfft(x);
// System.out.println("FFT before magnitude");
// IO.DisplayVector(x);
double[] mag = new double[n / 2 + 1];
mag[0] = x[0]; // DC frequency must be positive always
if (n == 1) {
return mag;
}
mag[n / 2] = Math.abs(x[n / 2]); // pi (meaning: fs / 2)
for (i = 1; i < n / 2; i++) {
mag[i] = Math.sqrt(x[i] * x[i] + x[n - i] * x[n - i]);
// System.out.println(mag[i] + " " + x[i] + " " + x[n-i]);
}
// IO.DisplayVector(mag);
return mag;
}
/**
* Calculates the power (magnitude squared) spectrum of a real signal. The
* returned vector contains only the positive frequencies.
*/
public double[] calculateFFTPower(double inputData[]) {
int i, n;
n = 1 << this.logm;
// System.out.println("magnitude test");
// double[] dtest = DSP.DFTMagnitude(inputData);
// IO.DisplayVector(dtest);
float[] x = new float[n];
for (i = 0; i < inputData.length; i++) {
x[i] = (float) inputData[i];
}
rsfft(x);
// System.out.println("FFT before magnitude");
// IO.DisplayVector(x);
double[] mag = new double[n / 2 + 1];
mag[0] = x[0]; // DC frequency must be positive always
if (n == 1) {
return mag;
}
mag[n / 2] = Math.abs(x[n / 2]); // pi (meaning: fs / 2)
for (i = 1; i < n / 2; i++) {
mag[i] = x[i] * x[i] + x[n - i] * x[n - i];
// mag[i] = Math.sqrt(x[i]*x[i]+x[n-i]*x[n-i]);
// System.out.println(mag[i] + " " + x[i] + " " + x[n-i]);
}
// IO.DisplayVector(mag);
return mag;
}
/**
* In place calculation of FFT magnitude.
*/
public void FFTMagnitude(float x[]) {
int i, n;
rsfft(x);
n = 1 << this.logm;
if (n == 1)
return;
for (i = 1; i < n / 2; i++) {
x[i] = (float) Math.sqrt(x[i] * x[i] + x[n - i] * x[n - i]);
x[n - i] = x[i];
}
// Aldebaro modification:
x[n / 2] = Math.abs(x[n / 2]);
}
void rsfft(float x[]) {
/* creat table */
// if(logm>=4) creattab(logm);
/* Call recursive routine */
rsrec(x, logm);
/* Output array unshuffling using bit-reversed indices */
if (logm > 1) {
BR_permute(x, logm);
return;
}
}
/*
* -------------------------------------------------------------------- *
* Inverse transform for real inputs *
* --------------------------------------------------------------------
*/
void rsifft(float x[]) {
int i, m;
float fac;
int xp;
/* Output array unshuffling using bit-reversed indices */
if (logm > 1) {
BR_permute(x, logm);
}
x[0] *= 0.5;
if (logm > 0)
x[1] *= 0.5;
/* creat table */
// if(logm>=4) creattab(logm);
/* Call recursive routine */
rsirec(x, logm);
/* Normalization */
m = 1 << logm;
fac = (float) 2.0 / m;
xp = 0;
for (i = 0; i < m; i++) {
x[xp++] *= fac;
}
}
/*
* -------------------------------------------------------------------- *
* Creat multiple fator table *
* --------------------------------------------------------------------
*/
void creattab(int logm) {
int m, m2, m4, m8, nel, n, rlogm;
int cn, spcn, smcn, c3n, spc3n, smc3n;
double ang, s, c;
tab = new float[logm - 4 + 1][6 * ((1 << logm) / 4 - 2)];
for (rlogm = logm; rlogm >= 4; rlogm--)
{
m = 1 << rlogm;
m2 = m / 2;
m4 = m2 / 2;
m8 = m4 / 2;
nel = m4 - 2;
/* Initialize pointers */
cn = 0;
spcn = cn + nel;
smcn = spcn + nel;
c3n = smcn + nel;
spc3n = c3n + nel;
smc3n = spc3n + nel;
/* Compute tables */
for (n = 1; n < m4; n++) {
if (n == m8)
continue;
ang = n * TWOPI / m;
c = Math.cos(ang);
s = Math.sin(ang);
tab[rlogm - 4][cn++] = (float) c;
tab[rlogm - 4][spcn++] = (float) (-(s + c));
tab[rlogm - 4][smcn++] = (float) (s - c);
ang = 3 * n * TWOPI / m;
c = Math.cos(ang);
s = Math.sin(ang);
tab[rlogm - 4][c3n++] = (float) c;
tab[rlogm - 4][spc3n++] = (float) (-(s + c));
tab[rlogm - 4][smc3n++] = (float) (s - c);
}
}
}
/*
* -------------------------------------------------------------------- *
* Recursive part of the RSFFT algorithm. Not externally * callable. *
* --------------------------------------------------------------------
*/
void rsrec(float x[], int logm) {
int m, m2, m4, m8, nel, n;
int x0 = 0;
int xr1, xr2, xi1;
int cn = 0;
int spcn = 0;
int smcn = 0;
float tmp1, tmp2;
double ang, c, s;
/* Check range of logm */
try {
if ((logm < 0) || (logm > MAXLOGM)) {
System.err.println("FFT length m is too big: log2(m) = " + logm
+ "is out of bounds [" + 0 + "," + MAXLOGM + "]");
throw new OutofborderException(logm);
}
} catch (OutofborderException e) {
throw new OutOfMemoryError();
}
/* Compute trivial cases */
if (logm < 2) {
if (logm == 1) { /* length m = 2 */
xr2 = x0 + 1;
tmp1 = x[x0] + x[xr2];
x[xr2] = x[x0] - x[xr2];
x[x0] = tmp1;
return;
} else if (logm == 0)
return; /* length m = 1 */
}
/* Compute a few constants */
m = 1 << logm;
m2 = m / 2;
m4 = m2 / 2;
m8 = m4 / 2;
/* Build tables of butterfly coefficients, if necessary */
// if ((logm >= 4) && (tab[logm-4][0] == 0)) {
/* Allocate memory for tables */
// nel = m4 - 2;
/*
* if ((tab[logm-4] = (float *) calloc(3 * nel, sizeof(float))) == NULL)
* { printf("Error : RSFFT : not enough memory for cosine tables.\n");
* error_exit(); }
*/
/* Initialize pointers */
// tabi=logm-4;
// cn =0; spcn = cn + nel; smcn = spcn + nel;
/* Compute tables */
/*
* for (n = 1; n < m4; n++) { if (n == m8) continue; ang = n *
* (float)TWOPI / m; c = Math.cos(ang); s = Math.sin(ang);
* tab[tabi][cn++] = (float)c; tab[tabi][spcn++] = (float)(- (s + c));
* tab[tabi][smcn++] =(float)( s - c); } }
*
Liuyuew
- 粉丝: 0
- 资源: 1
最新资源
- java病毒广播模拟.zip
- Java正在成长但不仅仅是Java Java成长路线,但学到的不仅仅是Java .zip
- amis 是一个低代码前端框架(它使用 JSON 配置来生成页面).zip
- 包括一些学习笔记,案例,后期还会添加java小游戏.zip
- Java实现的包含题库编辑、抽取题组卷、试题分析、在线考试等模块的Web考试系统 .zip
- 北航大一软件工程小学期java小游戏.zip
- 基于Spring MVC MyBatis FreeMarker和Vue.js的在线考试系统前端设计源码
- 初学Java时花费12天做的一款小游戏.zip
- Java字节码工程工具包.zip
- 一个未完成的泥巴游戏尝试.zip大作业实践
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
- 5
- 6
前往页