【问题标题】:JTransform FFT returning infinityJTransform FFT 返回无穷大
【发布时间】:2018-08-04 14:13:19
【问题描述】:

我正在尝试使用 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);               
        }

【问题讨论】:

  • 由于您在阅读 wav 文件时似乎遇到了问题,也许您可​​以将您的问题集中在这方面,并提供有关您正在使用的 WavFile 实现以及您正在使用的音频样本(例如采样率、每个样本的字节数、通道数、编码格式等)

标签: java signal-processing fft


【解决方案1】:

感谢您的回答。我能够完全解决这个问题。这是代码中的一个愚蠢的错误。每次转换数据时,它都会在样本中替换其时域等效值,其大小为 512。将时域数据复制到 fft 缓冲区的代码行采用了第 0 帧的大小参数,该参数首先被转换,而不是采用当前正在处理的帧的大小。这引起了所有的麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2022-01-23
    相关资源
    最近更新 更多