Holen Sie sich sound-Frequenz mit Android-FFT
Folgende code zeigt nur eine Grafik, jedoch will ich den sound Frequenz. Ich bin versucht zu Stimme aufnehmen und Echtzeit-Frequenz, so dass ich spielen kann, eine piano-oder Gitarren-sound und finden Sie die Frequenz.
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();
}
}
}
Wie kann ich die Frequenz von diesem code?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre FFT-code nicht geben Sie die Frequenz. Es gibt Sie ein array von komplexen Werte auf eine Reihe von verschiedenen Frequenzen. Und es könnte ein Fehler in Ihrem code, wenn Sie nur einen Blick auf die "real" - oder Cosinus-Komponente des FFT-Ergebnisses statt der vector magnitude von jedem komplexen Komponente.
Jedes element Ihres toTransform[i] array nach der FFT gibt Ihnen einen komplexen Wert für Frequenzen um oder in der Nähe (i * sampleRate /blockSize). Sie könnten finden, die maxima der Werte in diesem array schätzen Sie die Ungefähre Frequenz, bei der der Umfang am größten war. Man könnte auch interpolieren die maxima um diese zu verbessern, die Häufigkeit einzuschätzen.
Aber wenn Sie sind auf der Suche für ein pitch-Schätzung (einer Gitarre beachten zum Beispiel), das kann sehr unterschiedlich sein, von einer peak-Frequenz schätzen. Vielleicht möchten Sie vielleicht einen Blick in einige pitch estimation-algorithmen statt.