Calculating an FFT from an audio file

I used to ask a question about Get frequency wav sound using FFT and the Complex class ,

There I need to calculate the FFT value from the AudioRecord input β†’ from the microphone, I somehow managed to get the FFT value ...

Now I need to calculate the FFT value from the * .wav audio file that I saved before, I saved the sound in the "raw" folder inside the "res" folder from my project

I still use the same FFT class: http://www.cs.princeton.edu/introcs/97data/FFT.java

A complex class for this: http://introcs.cs.princeton.edu/java/97data/Complex.java.html

I use this method to read the audio file from my source folder n, then I call the calculateFFT method to go with it

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); } 

Convert to Byte Method

 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_CHANNELS,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; } 

And this is the CalculateFFT method

 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; } 

I also used this CalculateFFT method to process sound from AudioRecorder β†’ with mic input to ... I was able to get the value from AudioRecorder, but I was not able to get the value from my audio file ... I'm not planning to play audio. I just need to process it using FFT.

Are there any errors in my code ?: o It seems that I can not get the value from the Asli () method; But I don’t know which part is wrong.

Any help would be appreciated ... :) Thanks

+7
source share
1 answer

I spent most of the morning coding of the solution for this, using fragments of Java FFT snippets that I found ... but then I came across this amazingly malicious Google code project that has a bunch of usage classes to do the signal processing in WAV and MP3 files.

https://github.com/Uriopass/audio-analysis Previously, SVN export was in Google code here: https://storage.googleapis.com/google-code-archive-source/v2/code.google.com/audio- analysis / source-archive.zip

Now it becomes Extremely simple:

 WaveDecoder decoder = new WaveDecoder(new FileInputStream(wavFile)); FFT fft = new FFT(1024, wavFileObj.getSampleRate()); 

Now you can use the fft object to perform various calculations. They have many great examples, such as creating a list containing a spectral stream:

  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); } 

My company needed me to be able to analyze some sound to see if there was any expectation. So first I generated a WAV file for an example that had trick music. Then I grabbed a few sounds from one of your examples that did not have music to hold. Now all that remains is to average the wav spectral flux and I am tuned.

Note. I couldn't just take amplitudes ... but the Fourier transform has frequencies that I could use correctly to make my comparison.

I love math.

+6
source

Source: https://habr.com/ru/post/949091/


All Articles