2012-02-17 1 views
3

Le code suivant montre juste un graphique, mais je veux la fréquence du son. J'essaie d'enregistrer la voix et d'obtenir la fréquence en temps réel, de sorte que je puisse jouer un son de piano ou de guitare et trouver la fréquence.Obtenir la fréquence sonore avec Android FFT

public class AudioProcessing extends Activity implements OnClickListener { 

int frequency = 8000; 
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 

private RealDoubleFFT transformer; 
int blockSize = 256; 

Button startStopButton; 
boolean started = false; 

RecordAudio recordTask; 

ImageView imageView; 
Bitmap bitmap; 
Canvas canvas; 
Paint paint; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    startStopButton = (Button) this.findViewById(R.id.StartStopButton); 
    startStopButton.setOnClickListener(this); 

    transformer = new RealDoubleFFT(blockSize); 

    imageView = (ImageView) this.findViewById(R.id.ImageView01); 
    bitmap = Bitmap.createBitmap((int) 256, (int) 100, 
      Bitmap.Config.ARGB_8888); 
    canvas = new Canvas(bitmap); 
    paint = new Paint(); 
    paint.setColor(Color.GREEN); 
    imageView.setImageBitmap(bitmap); 
} 



private class RecordAudio extends AsyncTask<Void, double[], Void> { 
    @Override 
    protected Void doInBackground(Void... params) { 
     try { 
      int bufferSize = AudioRecord.getMinBufferSize(frequency, 
        channelConfiguration, audioEncoding); 

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

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

      audioRecord.startRecording(); 

      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) { 
      Log.e("AudioRecord", "Recording Failed"); 
     } 

     return null; 
    } 

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

public void onClick(View v) { 
    if (started) { 
     started = false; 
     startStopButton.setText("Start"); 
     recordTask.cancel(true); 
    } else { 
     started = true; 
     startStopButton.setText("Stop"); 
     recordTask = new RecordAudio(); 
     recordTask.execute(); 
    } 
} 
    } 

Comment puis-je obtenir la fréquence de ce code?

Répondre

3

Votre code FFT ne vous donne pas de fréquence. Il vous donne un tableau de valeurs complexes à un groupe de fréquences différentes. Et il peut y avoir un bug dans votre code si vous regardez simplement le composant "réel" ou cosinus du résultat FFT au lieu de la magnitude vectorielle de chaque composant complexe. Chaque élément de votre tableau toTransform [i] après la FFT vous donne une valeur complexe pour les fréquences proches ou proches (i * sampleRate/blockSize). Vous pourriez trouver les maxima des amplitudes de ce tableau pour estimer la fréquence approximative à laquelle l'amplitude était la plus grande. Vous pouvez également interpoler les maxima pour améliorer cette estimation de fréquence.

Mais si vous recherchez une estimation de hauteur (d'une note de guitare par exemple), cela peut être très différent d'une estimation de fréquence de crête. Peut-être que vous pourriez vouloir regarder dans quelques algorithmes d'estimation de lancement à la place.

Questions connexes