1

Java で小さな離散フーリエ変換を記述して、明確な 400 Hz 正弦波信号 (pcm 符号付きショートとして 1 秒) で振幅スペクトルを見つけようとしています。

最初に、複素数の 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 では 800/2 = 400 Hz が最大周波数として表示されるため、800 サンプルのみを選択した場合でも 400 Hz でピークが表示されるべきではありませんか?

800 サンプルを選択すると 20 Hz になり、1600 サンプルを選択すると 40 Hz になり、これは常に 1/40 * サンプル レートになります。

私は一体何を見逃しているのですか、それとも間違っていたのですか? 結果は奇妙です..

複素数値で逆 DFT を実行すると、オーディオ信号を再構築できることに注意してください。

4

1 に答える 1