问题描述
我花了大部分时间在上午,使用发现的FFT Java代码片段为该代码编写解决方案…但是后来我偶然发现了这个极为出色的Google代码项目,该项目具有一堆用于执行信号处理任务的util类在WAV和MP3文件上都一样。
https://github.com/Uriopass/audio- analysis 以前SVN导出是在以下Google代码上进行的:https ://storage.googleapis.com/google-code-archive-source/v2/code.google.com/audio- analysis / source-archive.zip
现在,它变得异常简单:
WaveDecoder decoder = new WaveDecoder(new FileInputStream(wavFile));
FFT fft = new FFT(1024, wavFileObj.getSampleRate());
现在,您可以使用fft对象进行各种计算。他们有很多很好的例子,例如生成包含光谱通量的列表:
float[] samples = new float[1024];
float[] spectrum = new float[1024 / 2 + 1];
float[] lastSpectrum = new float[1024 / 2 + 1];
List<Float> spectralFlux = new ArrayList<Float>();
while (decoder.readSamples(samples) > 0) {
fft.forward(samples);
System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length);
System.arraycopy(fft.getSpectrum(), 0, spectrum, 0, spectrum.length);
float flux = 0;
for (int i = 0; i < spectrum.length; i++)
flux += (spectrum[i] - lastSpectrum[i]);
spectralFlux.add(flux);
}
我的公司需要我一种分析音频的方法,以查看是否发生了预期的保持音乐。因此,首先,我为一个具有保留音乐的示例生成了一个WAV文件。然后,我捕获了其中一个没有保留音乐的示例的一些音频。现在剩下的就是对wav的频谱通量求平均,我就开始了。
注意:我不能简单地获取幅度…但是傅立叶变换具有可以正确用于进行比较的频率。
我爱数学。
解决方法
之前,我问过有关使用FFT和Complex
class获取频率wav音频的问题,
在那里,我需要从AudioRecord输入->从麦克风计算FFT值,以某种方式设法获得FFT值…
现在,我需要从之前保存的* .wav音频文件中计算FFT值,然后将音频保存到项目中“ res”文件夹中的“ raw”文件夹中
我仍然使用相同的FFT类:http :
//www.cs.princeton.edu/introcs/97data/FFT.java
与之配套的复杂类:http
:
//introcs.cs.princeton.edu/java/97data/Complex.java.html
我使用这种方法从原始文件夹中读取音频文件,然后调用方法calculateFFT来处理它
private static final int RECORDER_BPP = 16;
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private void asli(){
int counter = 0;
int data;
InputStream inputStream = getResources().openRawResource(R.raw.b1);
DataInputStream dataInputStream = new DataInputStream(inputStream);
List<Integer> content = new ArrayList<Integer>();
try {
while ((data = dataInputStream.read()) != -1) {
content.add(data);
counter++; }
} catch (IOException e) {
e.printStackTrace();}
int[] b = new int[content.size()];
int cont = 0;
byte[] audio = convertArray(b);
}
转换为字节的方法
public byte[] convertArray(int[] array) {
int minBufferSize = AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,RECORDER_SAMPLERATE,RECORDER_AUDIO_ENCODING,minBufferSize,AudioTrack.MODE_STREAM);
byte[] newarray = new byte[array.length];
for (int i = 0; i < array.length; i++) {
newarray[i] = (byte) ((array[i]) & 0xFF); }
absNormalizedSignal = calculateFFT(newarray);
return newarray;
}
这是CalculateFFT方法
public double[] calculateFFT(byte[] signal)
{
final int mNumberOfFFTPoints =1024;
double mMaxFFTSample;
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;
}
我也使用了CalculateFFT方法来处理AudioRecorder的音频->以前是通过麦克风输入的…我设法从AudioRecorder取得了价值,但我无法从音频文件中获得价值…我没有计划播放音频..我只需要使用FFT处理它。
我的代码有什么问题吗?:o似乎我无法从方法Asli()获得价值;但是我不知道哪一部分错了。
任何帮助将不胜感激… :)谢谢