我想获取一个大小约为 70-80k 的字节数组,并将它们从时域转换为频域(可能使用 DFT)。到目前为止,我一直在关注 wiki 并获得了此代码。
for (int k = 0; k < windows.length; k++) {
double imag = 0.0;
double real = 0.0;
for (int n = 0; n < data.length; n++) {
double val = (data[n])
* Math.exp(-2.0 * Math.PI * n * k / data.length)
/ 128;
imag += Math.cos(val);
real += Math.sin(val);
}
windows[k] = Math.sqrt(imag * imag + real
* real);
}
据我所知,这可以找到每个频率窗口/箱的幅度。然后我穿过窗户,找到震级最高的那一个。我在该频率上添加了一个标志,以便在重建信号时使用。我检查重建的信号是否与我的原始数据集匹配。如果它没有找到下一个最高频率窗口,并在重建信号时标记它。
这是我用来重建信号的代码,我很确定这是非常错误的(它应该执行 IDFT):
for (int n = 0; n < data.length; n++) {
double imag = 0.0;
double real = 0.0;
sinValue[n] = 0;
for (int k = 0; k < freqUsed.length; k++) {
if (freqUsed[k]) {
double val = (windows[k] * Math.exp(2.0 * Math.PI * n
* k / data.length));
imag += Math.cos(val);
real += Math.sin(val);
}
}
sinValue[n] = imag* imag + real * real;
sinValue[n] /= data.length;
newData[n] = (byte) (127 * sinValue[n]);
}
freqUsed 是一个布尔数组,用于标记在重建信号时是否应使用频率窗口。
无论如何,这是出现的问题:
- 即使使用了所有频率窗口,也不会重建信号。这可能是由于...
- 有时 Math.exp() 的值太高,因此返回无穷大。这使得难以获得准确的计算。
- 虽然我一直关注 wiki 作为指南,但很难判断我的数据是否有意义。这使得测试和识别问题变得困难。
脱离问题:
我对此很陌生,并不完全了解所有内容。因此,感谢任何帮助或见解。感谢您花时间阅读所有内容,并提前感谢您提供的任何帮助。任何帮助真的会很好,即使你认为我这样做是最糟糕的可怕方式,我想知道。再次感谢。
-
编辑:
所以我更新了我的代码,如下所示:
for (int k = 0; k < windows.length; k++) {
double imag = 0.0;
double real = 0.0;
for (int n = 0; n < data.length; n++) {
double val = (-2.0 * Math.PI * n * k / data.length);
imag += data[n]*-Math.sin(val);
real += data[n]*Math.cos(val);
}
windows[k] = Math.sqrt(imag * imag + real
* real);
}
对于原始变换和:
for (int n = 0; n < data.length; n++) {
double imag = 0.0;
double real = 0.0;
sinValue[n] = 0;
for (int k = 0; k < freqUsed.length; k++) {
if (freqUsed[k]) {
double val = (2.0 * Math.PI * n
* k / data.length);
imag += windows[k]*-Math.sin(val);
real += windows[k]*Math.cos(val);
}
}
sinValue[n] = Math.sqrt(imag* imag + real * real);
sinValue[n] /= data.length;
newData[n] = (byte) (Math.floor(sinValue[n]));
}
为逆变换。虽然我仍然担心它不能正常工作。我生成了一个包含单个正弦波的数组,它甚至无法分解/重建它。关于我缺少什么的任何见解?