我正在尝试用Java编写一个小的离散傅里叶变换来查找清晰的400 Hz正弦信号中的幅度谱(1秒作为pcm signed-short)
首先,我计算复数值的DFT:
public void berechneDFT(int abtastwerte) {
int i;
int N = abtastwerte;
ReX = new double[N/2+1];
ImX = new double[N/2+1];
TextFileOperator tfo = new TextFileOperator(file.substring(0, file.length()-4)+"_DFT.txt");
try {
tfo.openOutputStream();
tfo.writeString("ReX ImX\n");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// real-Anteil berechnen
for (i=0, ReX[i] = 0, ImX[i] = 0; i <= N/2; i++)
{
for(int n=0; n < N; n++)
{
ReX[i] += x[n] * Math.cos( (2.0 * Math.PI * n * i) / (double) N);
ImX[i] += - (x[n] * Math.sin( (2.0 * Math.PI * n * i) / (double) N));
}
tfo.writeString(ReX[i] +" "+ImX[i]+"\n");
}
x = null;
tfo.closeOutputStream(); // flush
System.out.println("Anteile berechnet.");
}
然后我尝试计算幅度谱:
public void berechneBetragsSpektrum() {
int N = ReX.length;
TextFileOperator tfo = new TextFileOperator("betragsspektrum_400hz.txt");
try {
tfo.openOutputStream();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
double powerAtFreq;
int marker = 0;
double maxPowerAtFreq = 0;
for(int i=0; i < N; i++)
{
double A1 = ReX[i] * ReX[i];
double A2 = ImX[i] * ImX[i];
powerAtFreq = Math.sqrt(A1+A2);
if(powerAtFreq > maxPowerAtFreq)
{
maxPowerAtFreq = powerAtFreq;
marker = i;
}
tfo.writeString(powerAtFreq+"\n");
}
tfo.closeOutputStream();
System.out.println("Stärkste Frequenz: "+(marker)+" Hz");
}
但由于某种原因,如果我选择检查所有16000个样本,我只会在'标记'中得到400 Hz的结果。但是如果我只选择800个样本,我不应该看到400 Hz的峰值,因为800我可以看到800/2 = 400 Hz作为最大频率?
我想代码中的一些小问题一定是错的,因为如果我选择800个样本,我会得到20 Hz,对于1600个样本,我得到40 Hz,这总是1/40 *采样率。
我到底错过了什么或做错了什么?结果很奇怪..
请注意,如果我使用复数值进行逆DFT,我可以再次重建音频信号!
答案 0 :(得分:0)
问题的答案是,如果计算傅立叶变换,幅度谱等,则指数显示需要计算其正确值的相对频率。