提取wav文件频谱的java代码
时间: 2023-05-29 20:05:45 浏览: 141
以下是提取WAV文件频谱的Java代码示例:
```java
import javax.sound.sampled.*;
import java.io.*;
public class SpectrumAnalyzer {
public static void main(String[] args) {
try {
File file = new File("audio.wav"); // Replace with your WAV file path
AudioInputStream audioStream = AudioSystem.getAudioInputStream(file);
AudioFormat format = audioStream.getFormat();
byte[] bytes = new byte[(int) (audioStream.getFrameLength() * format.getFrameSize())];
audioStream.read(bytes);
int[] audioData = new int[bytes.length / 2];
for (int i = 0, j = 0; i < bytes.length; i += 2, j++) {
audioData[j] = ((bytes[i] & 0xff) | (bytes[i + 1] << 8));
}
int sampleRate = (int) format.getSampleRate();
int numChannels = format.getChannels();
FFT fft = new FFT(audioData.length, sampleRate);
double[] magnitude = new double[audioData.length];
double[] phase = new double[audioData.length];
fft.fft(audioData, magnitude, phase);
double[] frequencies = fft.getFrequencyArray();
double[] power = new double[frequencies.length];
for (int i = 0; i < frequencies.length; i++) {
power[i] = 20 * Math.log10(magnitude[i]);
}
// Do something with the power array, e.g. plot it on a graph
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
}
}
class FFT {
private final int n, m;
private final double[] cos;
private final double[] sin;
private final double[] window;
public FFT(int n, int sampleRate) {
this.n = n;
this.m = (int) (Math.log(n) / Math.log(2));
cos = new double[n / 2];
sin = new double[n / 2];
window = new double[n];
for (int i = 0; i < n / 2; i++) {
cos[i] = Math.cos(-2 * Math.PI * i / n);
sin[i] = Math.sin(-2 * Math.PI * i / n);
}
for (int i = 0; i < n; i++) {
window[i] = 0.5 * (1 - Math.cos(2 * Math.PI * i / (n - 1)));
}
}
public void fft(int[] x, double[] magnitude, double[] phase) {
for (int i = 0; i < n; i++) {
x[i] *= window[i];
}
for (int i = 0; i < n; i++) {
int j = Integer.reverse(i) >>> (32 - m);
if (j > i) {
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
for (int s = 2; s <= n; s *= 2) {
for (int i = 0; i < n; i += s) {
for (int j = 0; j < s / 2; j++) {
int tIndex = n / s * j;
int index1 = i + j;
int index2 = i + j + s / 2;
double tCos = cos[tIndex];
double tSin = sin[tIndex];
double tRe = tCos * x[index2] + tSin * x[index2 + 1];
double tIm = tCos * x[index2 + 1] - tSin * x[index2];
x[index2] = x[index1] - tRe;
x[index2 + 1] = x[index1 + 1] - tIm;
x[index1] += tRe;
x[index1 + 1] += tIm;
}
}
}
for (int i = 0; i < n / 2; i++) {
magnitude[i] = Math.sqrt(x[2 * i] * x[2 * i] + x[2 * i + 1] * x[2 * i + 1]);
phase[i] = Math.atan2(x[2 * i + 1], x[2 * i]);
}
}
public double[] getFrequencyArray() {
double[] frequency = new double[n / 2];
for (int i = 0; i < n / 2; i++) {
frequency[i] = i * 1.0 * sampleRate / n;
}
return frequency;
}
}
```
该代码使用FFT算法计算了WAV文件的频谱,输出了幅度和相位数组,可以进一步处理这些数组并绘制频谱图。请注意,此代码仅适用于单声道WAV文件。如果要处理立体声文件,请根据需要修改代码。