Ich versuche, eine App zu implementieren, wo ich eine Pfeife einer bestimmten Frequenz (1000Hz - 1500Hz) erkennen kann, auch wenn es Umwelt Hintergrundgeräusche und nach einer Menge Forschung im Netz, ich habe FFT-Methoden verwendet, um zu versuchen, zu erkennen, ob die maximale Amplitude, die vom Mikrofon aufgenommen wird, mit der Frequenz des Pfeiftons übereinstimmt.Android Whistle Erkennung mit Mic
public void run() {
if (ar == null) {
bufferSize = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,bufferSize);
audioBuffer = new short[bufferSize];
ar.startRecording();
ar.read(audioBuffer, 0, bufferSize);
//Conversion from short to double
double[] micBufferData = new double[bufferSize];//size may need to change
final int bytesPerSample = 2; // As it is 16bit PCM
final double amplification = 1.0; // choose a number as you like
for (int index = 0, floatIndex = 0; index < (byte) bufferSize - bytesPerSample + 1; index += bytesPerSample, floatIndex++) {
double sample = 0;
for (int b = 0; b < bytesPerSample; b++) {
int v = audioBuffer[index + b];
if (b < bytesPerSample - 1 || bytesPerSample == 1) {
v &= 0xFF;
}
sample += v << (b * 8);
}
double sample32 = amplification * (sample/32768.0);
micBufferData[floatIndex] = sample32;
}
//Create Complex array for use in FFT
Complex[] fftTempArray = new Complex[bufferSize];
for (int i=0; i< (byte) bufferSize; i++)
{
fftTempArray[i] = new Complex(micBufferData[i], 0);
}
//Obtain array of FFT data
final Complex[] fftArray = FFT.fft(fftTempArray);
//final Complex[] fftInverse = FFT.ifft(fftTempArray);
//Create an array of magnitude of fftArray
double[] magnitude = new double[fftArray.length];
for (int i=0; i<fftArray.length; i++){
magnitude[i]= fftArray[i].abs();
}
double maxVal = -1.0;
int maxIndex = 1;
for(int j=0; j < fftArray.length/2; ++j) {
double v = magnitude[2*j] * magnitude[2*j] + magnitude[2*j+1] * magnitude[2*j+1];
if(v > maxVal) {
maxVal = v;
maxIndex = j;
}
}
maxFrequency = ((1.0 * 44100)/(1.0 * bufferSize)) * maxIndex;
}
runOnUiThread(new Runnable() {
@Override
public void run() {
if (isRunning) {
tv2.setText("Frequency Detected: " + maxFrequency);
}
}
});
}
Ich habe bereits ein Mikrofon Recorder einrichten und so weiter, aber ich kann nicht verstehen, was der Code tut und ich habe einige Fehler immer sagen, dass mein fftarray negativ ist. Könnte mir jemand helfen, in die richtige Richtung zu zeigen? Oder gibt es einen besseren Weg, eine Pfeifenerkennung zu implementieren? Ich verwende Code von here. Ich bekomme ein N ist nicht auf die Kraft von 2 Ausnahme geworfen wird.
Was meinen Sie verstehen Sie nicht, was der Code tut? Es gehört nicht dir? – stackoverflowuser2010
Wenn Sie herausfinden möchten, ob bestimmte Frequenzen in einem Sound vorhanden sind, ist FFT der richtige Weg. Was genau ist deine Frage? – stackoverflowuser2010
Ich erhalte einige Fehler, wenn ich versuche, den Code auszuführen. Ich bekomme java.lang.RuntimeException: N ist keine Potenz von 2 für den letzten Komplex [] fftArray = FFT.fft (fftTempArray); –