2014-03-25 43 views
0

我已經看過這裏的每一個答案,我不明白他們...我能夠獲得圖表,但我怎麼纔能有一個單一的值爲當前的頻率...我會欣賞代碼的答案,而不是數學的人..在android中,我怎樣才能實時獲得正確的頻率值?

public class RecordAudio extends AsyncTask<Void, double[], Void> { 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     try { 
      // int bufferSize = AudioRecord.getMinBufferSize(frequency, 
      // AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 
      int bufferSize = AudioRecord.getMinBufferSize(frequency, 
        channelConfiguration, audioEncoding); 

      AudioRecord audioRecord = new AudioRecord(
        MediaRecorder.AudioSource.MIC, frequency, 
        channelConfiguration, audioEncoding, bufferSize); 

      // double[] audioDataDoubles = new double[(blockSize*2)]; // Same values as above, as doubles 
      // ----------------------------------------------- 
      double[] re = new double[blockSize]; 
      double[] im = new double[blockSize]; 
      double[] magnitude = new double[blockSize]; 
      int sampleRate = 8000;        // Sample rate in Hz 

      short[] buffer = new short[blockSize]; 
      double[] toTransform = new double[blockSize]; 

      audioRecord.startRecording(); 

      // started = true; hopes this should true before calling 
      // following while loop 

      while (started) { 
       int bufferReadResult = audioRecord.read(buffer, 0, 
         blockSize); 

       for (int i = 0; i < blockSize && i < bufferReadResult; i++) { 
        toTransform[i] = (double) buffer[i]/32768.0; // signed 
        // 16 
       }          // bit 
       transformer.ft(toTransform); 



       publishProgress(toTransform); 



      } 

      audioRecord.stop(); 

     } catch (Throwable t) { 
      t.printStackTrace(); 
      Log.e("AudioRecord", "Recording Failed"); 
     } 
     return null; 
    } 
    public double Index2Freq(int i, double samples, int nFFT) { 
     return (double) i * (samples/nFFT/2.); 
    } 
    public int calculateF(int sampleRate, double [] audioData){ 

     int numSamples = audioData.length; 
     int numCrossing = 0; 
     for (int p = 0; p < numSamples-1; p++) 
     { 
      if ((audioData[p] > 0 && audioData[p + 1] <= 0) || 
        (audioData[p] < 0 && audioData[p + 1] >= 0)) 
      { 
       numCrossing++; 
      } 
     } 

     float numSecondsRecorded = (float)numSamples/(float)sampleRate; 
     float numCycles = numCrossing/2; 
     float frequency = numCycles/numSecondsRecorded; 

     return (int)frequency; 
    } 

    @Override 
    protected void onProgressUpdate(double[]... toTransform) { 

     canvas.drawColor(Color.BLACK); 

     for (int i = 0; i < toTransform[0].length; i++) { 
      int x = i; 
      int downy = (int) (100 - (toTransform[0][i] * 10)); 
      int upy = 100; 



      canvas.drawLine(x, downy, x, upy, paint); 
     } 

     imageView.invalidate(); 

      TxtV.setText("Frequency = "+String.valueOf(calculateF(8000, toTransform[0]))); 

     // TODO Auto-generated method stub 
     // super.onProgressUpdate(values); 
    } 

} 
+0

也許你不喜歡你找到的答案,因爲現實並不簡單。什麼是隻有一個頻率存在?而且你發現的組件的頻率分辨率受到你計算傅里葉變換的樣本數量的限制(儘管你可以通過零填充作用到有限的程度)。 –

+0

我基本上正在尋找基於toTransform [0]元素得到正確計算頻率的代碼 – Pedrum

+1

尋找最強的一個,將bin號碼轉換回頻率。如果發現混淆,請使用已知輸入運行測試用例。 –

回答

0

如果電流頻率,你的意思是關於捕獲的音頻,實現現場聲音是由頻率的數量龐大的,所以你永遠不會得到的只是一個頻率的結果。

即使對於單個音高(對於零噪聲中的合成純正弦測試數據除外)也是如此。

+0

然後我想要做與大多數其他應用程序一樣的事情......它們以某種方式提供高度準確的頻率! – Pedrum