我正在研究一個項目,我必須分析.wav
文件,這對我來說基本上是能夠顯示出現在所述文件中的頻率。我使用WavFile
類來讀取文件,然後我使用JTransforms
類(我實際上做了realForward
,因爲我只餵它實數)對它們進行FFT。Java .wav文件頻率分析 - 不正確的頻率
一切似乎工作正常,直到我將數據輸入到Excel中:我在第一列(我正在測試的文件爲1-8000)中輸出一個行計數,然後將FFT的輸出下一列。我饋送的文件是一個簡單的單頻聲音,頻率爲440Hz,持續時間爲1秒。
看到圖表後,出現了一個問題:我有一個單一的頻率峯值,這正是我所期望的,但峯值位於880的位置,這是實際頻率的兩倍。有人可以向我解釋爲什麼?
獎勵問題:爲什麼我會得到e-16
左右的值?除峯值以外的其他值都應爲0,對嗎? (我通過在每次獲得的數據是<= 1
時寫入0來解決此問題 - 請參閱下面的代碼)。也許這是「噪音」?
代碼:
有兩個類。第一個,readWav
用於讀取.wav
文件。第二個,wavFFT
,是實際上FFT數據的人。
代碼readWav.java
:
import WavFile.*;
import java.io.*;
public class readWav {
// getter methods
public static long getWavFrames(File file)
{
// try loop to catch any exception
try {
// open the wav file
WavFile wavFile = WavFile.openWavFile(file);
// return the number of frames
return wavFile.getNumFrames();
} catch (Exception e) {
System.err.println(e);
// error value
return -1;
}
}
public static int getWavChannels(File file)
{
// try loop to catch any exception
try {
WavFile wavFile = WavFile.openWavFile(file);
return wavFile.getNumChannels();
} catch (Exception e) {
System.err.println(e);
// error value
return -1;
}
}
public static double[] getWavData(File file)
{
// try loop to catch any exception
try {
// open the file
WavFile wavFile = WavFile.openWavFile(file);
// use the getter method to get the channel number (should be mono)
int numChannels = getWavChannels(file);
// same, but with the frame getter method
int numFrames = (int) getWavFrames(file); // possible data loss
// create a buffer the size of the number of frames
double[] buffer = new double[numFrames * numChannels];
// Read frames into buffer
wavFile.readFrames(buffer, numFrames);
// Close the wavFile
wavFile.close();
return buffer;
} catch (Exception e) {
System.err.println(e);
// throw an error, if this runs something went wrong in reading the .wav file
throw new RuntimeException("[could not read wav file " + file + "]");
}
}
// main method, solely for testing purposes
public static void main(String[] args)
{
// test, everything seems to be working
File fichier_son = new File("son/freq1.wav");
double[] test = getWavData(fichier_son);
for(int i = 0; i<test.length; i++){
System.out.println(test[i]);
}
}
}
代碼wavFFT.java
:
import org.jtransforms.fft.DoubleFFT_1D;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
public class wavFFT {
public static double[] realFFT(File file)
{
// Get the .wav data using the readWav class
double[] data_to_fft = readWav.getWavData(file);
/* Get the length of the array.
Since we are feeding real numbers into the fft,
the length of the array should be equal to the
number of frames, which we get using the readWav class. */
int n = (int) readWav.getWavFrames(file);
// Make a new fft object
DoubleFFT_1D fft = new DoubleFFT_1D(n);
// Perform the realForward fft
fft.realForward(data_to_fft);
// Return the final data
return data_to_fft;
}
public static void writeToFile(File in, File out) throws IOException
{
PrintWriter print_out = new PrintWriter(out);
int i;
double[] data_to_file = realFFT(in);
for(i=0; i<data_to_file.length; i++){
if(data_to_file[i] > 1){
print_out.println(data_to_file[i]);
} else {
print_out.println(0);
}
}
print_out.close();
}
// main method, solely for testing purposes
public static void main(String[] args) {
File fichier_son = new File("son/freq1.wav");
double[] test = realFFT(fichier_son);
int i;
for(i=0; i<test.length; i++){
System.out.println(test[i]);
}
try{
writeToFile(fichier_son, new File("datafiles/output.txt"));
} catch (IOException e){
System.out.println("error");
}
}
}
嗨。當我運行你的代碼時,我會出現一個'WavFile包不存在'的錯誤。這是爲什麼?如何克服它? – Learner
@VibhavChaddha您尚未在項目中導入WavFile類。我在我的答案中鏈接到它。 – jimkokko5
@VibhavChaddha取決於你使用的IDE。我會建議谷歌搜索。 – jimkokko5