簡體   English   中英

JTransform FFT返回無窮大

[英]JTransform FFT returning infinity

我正在嘗試使用JTransforms在Java中獲取wav文件的fft數據。 我將wav文件讀為Double。 當我從JTRansforms對數據執行realforward()時,我得到的幾乎所有返回數據都是無窮大的。 同樣,一些不是無窮大的值在10 ^ 100左右或更高時非常高。 當我在Python上對相同數據執行fft時,會得到正確的結果。

我也注意到一些奇怪的事情。 當我從wav文件中讀取類型為long的數據時,它們與在Java中將其讀取為double時的數據不同。 實際上,在Java中將相同的文件讀取為double,而在python中讀取相同的文件則返回不同的數據。 但是,當我在Java中讀取一個wav文件時,而在python中讀取同一文件時,則會返回相似的數據。 我該怎么做才能獲得適當的fft結果。

這是我的代碼

        //Read File
        WavFile file = WavFile.openWavFile(new File( "Samples Set/Voice6T.wav" ) );
        file.display();

        ArrayList<ArrayList <Double>> samples = new ArrayList< ArrayList <Double>>();

        //Create Hanning Window
        ArrayList<Double> hann = new ArrayList<Double>();
        for (int i = 1; i <= fsize; i++ )
        {
            hann.add( 0.5d * ( 1d - (double) Math.cos( ( TWO_PI * i) / ( fsize - 1 )) ) );
        }

        //Here I divide data into 50% overlapping frames of length 256. fsize = 256
        //Also I multiply hanning window. Every frame is added to samples.
        ArrayList<Double> prev = new ArrayList<Double>();
        int len;

        {
            double f_half[] = new double[fsize/2];
            double s_half[] = new double [fsize/2];

            len = file.readFrames( f_half, fsize/2);
            len = file.readFrames( s_half, fsize/2);

            ArrayList<Double> fh = new ArrayList<Double>( Arrays.asList( Arrays.stream(f_half).boxed().toArray(Double[]::new) ) );
            prev = new ArrayList<Double>( Arrays.asList( Arrays.stream(s_half).boxed().toArray(Double[]::new) ) );

            fh.addAll(prev);

            ArrayList<Double> temp = (ArrayList<Double>) IntStream.range(0, hann.size())
                     .mapToObj(i -> fh.get(i) * hann.get(i))
                     .collect(Collectors.toList());

            samples.add(temp);
        }

        //I continue the above process in a loop.
        do
        {
            double f_half[] = new double[fsize/2];
            len = file.readFrames( f_half, fsize/2);
            if (len != fsize/2) break;

            ArrayList<Double> fh = new ArrayList<Double>( Arrays.asList( Arrays.stream(f_half).boxed().toArray(Double[]::new) ) );

            prev.addAll(fh);
            ArrayList<Double> t1 = prev;
            prev = fh;

            ArrayList<Double> temp = (ArrayList<Double>) IntStream.range(0, hann.size())
                     .mapToObj(i -> t1.get(i) * hann.get(i))
                     .collect(Collectors.toList());
            samples.add(temp);
        }
        while( len != 0 );

        //Next I perform FFT.
        DoubleFFT_1D fft = new DoubleFFT_1D( samples.get(0).size() );
        double fft_data[] = new double[ samples.get(0).size() ];

        for ( int i = 0; i < samples.size(); i++ )
        {
            System.arraycopy( ArrayUtils.toPrimitive( samples.get(i).toArray( new Double[samples.get(i).size()] ) ),
                    0, fft_data, 0, samples.get(0).size() );
            fft.realForward(fft_data);

            ArrayList<Double> temp = new ArrayList<Double>();
            for ( int j = 0; j < fft_data.length; j = j + 2 )
            {
                temp.add( Math.sqrt( (fft_data[j]*fft_data[j]) + (fft_data[j+1]*fft_data[j+1]) ) );
            }
            //Most of the data in fft_data and temp is Infinity.
            samples.set(i, temp);               
        }

謝謝回答。 我能夠完全解決問題。 這是代碼中的一個愚蠢的錯誤。 每次對數據進行轉換時,它都會替換其樣本中的時域等效文件,其大小為512。將時域數據復制到fft的緩沖區的代碼行采用的是幀0的size參數,該參數首先要進行轉換,而不是采用當前正在處理的幀的大小。 這引起了所有麻煩。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM