Java 为什么fft输出为每个声音输入提供相似的数据?
我试图得到一个预录声音的FFT结果,它被保存为.wav文件 对于我的FFT,我使用了FFT和发布的复数类(FFT)和(复数) 这是我现在拥有的代码,当我检查输出文件时,每个录音的值几乎相似。为什么呢Java 为什么fft输出为每个声音输入提供相似的数据?,java,android,Java,Android,我试图得到一个预录声音的FFT结果,它被保存为.wav文件 对于我的FFT,我使用了FFT和发布的复数类(FFT)和(复数) 这是我现在拥有的代码,当我检查输出文件时,每个录音的值几乎相似。为什么呢 double [] fftdata; File file; file = new File(AudioSavePathInDevice);
double [] fftdata;
File file;
file = new File(AudioSavePathInDevice);
File file2;
file2 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + number + "FFTvalues.txt");
byte[] soundBytes;
try {
InputStream inputStream = getContentResolver().openInputStream(Uri.fromFile(file));
soundBytes = toByteArray(inputStream);
fftdata = calculateFFT(soundBytes); <-- this is where I call my calculate FFT method
String sfftdata = Arrays.toString(fftdata);
FileOutputStream fos = new FileOutputStream(file2);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeUTF(sfftdata);
dos.close();
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch(Exception e){
e.printStackTrace();
}
计算FFT的方法
public double[] calculateFFT(byte[] signal)
{
final int mNumberOfFFTPoints = 4096;
double mMaxFFTSample;
double mPeakPos;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
double[] absSignal = new double[mNumberOfFFTPoints/2];
for(int i = 0; i < mNumberOfFFTPoints; i++){
temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
mMaxFFTSample = 0.0;
mPeakPos = 0;
for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
{
absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
if(absSignal[i] > mMaxFFTSample)
{
mMaxFFTSample = absSignal[i];
mPeakPos = i;
}
}
return absSignal;
}
public double[]calculateFFT(字节[]信号)
{
最终int mNumberOfFFTPoints=4096;
双样本;
双mPeakPos;
双温;
复合[]y;
复数[]复数信号=新复数[mNumberOfFFTPoints];
double[]absSignal=新的双精度[mNumberOfFFTPoints/2];
对于(int i=0;i
对我来说,您似乎没有正确解释.wav文件。一个wav文件可以有几种存储信息的方式(请参阅)有不同的编码,头信息不是音频,而是元信息,如比特率等。这不能被解释为音频信号。只需使用十六进制编辑器查看文件
其次,您不能假设两个字节代表您的音频输入,它可以是1字节,也可以是4位,甚至不是使用某种编码的纯整数,甚至不是存储在块中的整数(这意味着后面有一些长度信息,可能还有音频信号的其他描述)要知道有多少字节和它是什么样子,你必须解释标题信息
也许你可以阅读更多信息。问题是:你想实现什么?做FFT对于实时应用来说几乎是胡说八道。其次,它被称为DFT,因为你在记录时没有连续的信号。你想要的是每个频率的FIR带通滤波器……尽管你尝试的很酷,但让我想起了我的方法20年前。我的项目涉及识别和匹配为聋人制造的设备的声音轮廓。我需要这个FFT来计算峰值的欧几里德距离,以匹配声音轮廓。你介意看一下我的代码吗?要测试你的应用程序,只需生成几个正弦波,并检查结果是否符合你的要求我已经在Matlab上测试了我的音频信号,但我的应用程序并没有得到想要的输出。因此,我在这里征求一些建议。对于简单的峰值,不需要DFT。有更简单的方法。对我来说,看起来你只是在读取一个文件的字节,但是一个wave文件可能有几种不同的方式,你需要处理它er信息等。
public double[] calculateFFT(byte[] signal)
{
final int mNumberOfFFTPoints = 4096;
double mMaxFFTSample;
double mPeakPos;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
double[] absSignal = new double[mNumberOfFFTPoints/2];
for(int i = 0; i < mNumberOfFFTPoints; i++){
temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
mMaxFFTSample = 0.0;
mPeakPos = 0;
for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
{
absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));
if(absSignal[i] > mMaxFFTSample)
{
mMaxFFTSample = absSignal[i];
mPeakPos = i;
}
}
return absSignal;
}