在Android中使用FFTAndroid、FFT

2023-09-04 05:42:45 作者:泪别

我无法理解如何,我应该从话筒传递PCM数据,以我使用由彼得·Wendykier我该FFT类(它在JTransforms的DoubleFFT_1D类)。

I am having trouble understanding how I should pass PCM data from the mic to this FFT class I am using made by Piotr Wendykier (it's the DoubleFFT_1D class in JTransforms).

我想我必须返回一个实部和虚数,然后双击实数最终获得频率= 8000 * I / 1024,其中i为最高幅度的指数。

I think I have to return a real and imaginary number and then double the real number to eventually obtain Frequency = 8000 * i / 1024 where i is the index of the highest magnitude.

有人可以帮助我找到扮演一个音符的频率是多少?

Can someone help me in finding the frequency of a note played in?

我有一个记录类,如下所示:

I have a recording class as follows:

import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D;

...other various imports...

class recorderThread {

...public variables...

  public static void getFFtresult(){

         AudioRecord recorder;
            short[] audioData;
            int bufferSize;
            int samplerate = 8000;//or 8192?


            bufferSize= AudioRecord.getMinBufferSize(samplerate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
 AudioFormat.ENCODING_PCM_16BIT)*2; //get the buffer size to use with this audio record

recorder = new AudioRecord (AudioSource.MIC,samplerate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,bufferSize); //instantiate the AudioRecorder

recording=true; //variable to use start or stop recording
audioData = new short [bufferSize]; //short array that pcm data is put into.

int recordingLoops = 0;

 while (recordingLoops < 4) {  //loop while recording is needed

    if (recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED) // check to see if the recorder has initialized yet.
    if (recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)
          recorder.startRecording();  //check to see if the Recorder has stopped or is not recording, and make it record.

    else {
       recorder.read(audioData,0,bufferSize);   //read the PCM audio data into the audioData array

       DoubleFFT_1D fft = new DoubleFFT_1D(1023); //instance of DoubleFFT_1D class

       double[] audioDataDoubles = new double[1024];

       for (int j=0; j <= 1023; j++) { // get audio data in double[] format
           audioDataDoubles[j] = (double)audioData[j];          
       }

       fft.complexForward(audioDataDoubles);  //this is where it falls

       for (int i = 0; i < 1023; i++) {
           Log.v(TAG, "audiodata=" + audioDataDoubles[i] + " no= " + i);
       }

       recordingLoops++;
      }//else recorder started

    } //while recording

    if (recorder.getState()==android.media.AudioRecord.RECORDSTATE_RECORDING) recorder.stop(); //stop the recorder before ending the thread
    recorder.release(); //release the recorders resources
    recorder=null; //set the recorder to be garbage collected

   }//run

}//recorderThread

太感谢了!

推荐答案

如果你正在寻找一个音符的音高,你会发现,沥青是由FFT产生的光谱频率峰值往往是不同的,尤其是对低注意事项。

If you are looking for the pitch of a musical note, you will find that pitch is often different from the spectral frequency peak produced by an FFT, especially for lower notes.

要找到从复杂的FFT频率峰值,你需要计算双方的实部和虚结果矢量幅度。

To find the frequency peak from a complex FFT, you need to calculate the vector magnitude of both the real and imaginary results.

mag(i) = sqrt(real[i]*real[i] + imag[i]*imag[i]);