JTransform FFT返回无穷大



我正在尝试使用JTransforms获取java中wav文件的fft数据。我把wav文件读成Double。当我从JTRansforms对数据执行realforward((时,我得到的几乎所有返回数据都是无穷大的。此外,少数不是无穷大的值在10^100或更大的范围内非常高。当我在Python上对相同的数据执行fft时,我会得到正确的结果。

我还注意到一些奇怪的事情。当我从wav文件中以type 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的大小参数,而不是取当前正在处理的帧的大小。这引起了所有的麻烦。

最新更新