我有一个代码可以检测Android麦克风音频并计算频率。
虽然,我得到的频率与测试的频率不同。
例如。声音260Hz输出为62Hz
我不知道为什么我没有达到预期的频率
我正在使用的FFT来自网站
http://jfftpack.sourceforge.net/
请帮我解决这个问题。
/**
*
* @reference
* http://stackoverflow.com/questions/5511250/capturing-sound-for-
* analysis -and-visualizing-frequencies-in-android
*
*/
public class RecordAudio extends AsyncTask<Void, Double, Void> {
@Override
protected Void doInBackground(Void... arg0) {
try {
int bufferSize = AudioRecord.getMinBufferSize(sampleRate,
channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, sampleRate,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
audioRecord.startRecording();
while (started) {
double peakFreq = 0;
int bufferReadResult = audioRecord.read(buffer, 0,
blockSize);
int elementSize = blockSize / numSplit;
double max = 0;
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
toTransform[i] = (double) buffer[i] / 32768.0;
}
for (int i = 0; i < numSplit; i++) {
double[] chunk = new double[elementSize];
System.arraycopy(toTransform, i * elementSize, chunk,
0, elementSize);
HanningWindow(chunk, 0, chunk.length);
transformer.ft(chunk);
max = getMaxFrequency(chunk);
if (max > peakFreq)
peakFreq = max;
}
publishProgress(peakFreq);
}
audioRecord.stop();
} catch (Throwable t) {
t.printStackTrace();
Log.e("AudioRecord", "Recording Failed");
}
return null;
}
@Override
protected void onProgressUpdate(Double... frequency) {
if (frequency[0] > 25d)
textView.setText(Double.toString(frequency[0]));
}
private double getMaxFrequency(double[] fft) {
int i, mgIndex = 0, size = fft.length / 2;
double[] re = new double[size];
double[] im = new double[size];
double[] mg = new double[size];
i = 0;
re[i] = fft[i];
im[i] = 0;
mg[i] = Math.sqrt(re[i] * re[i]);
for (i = 1; i < size - 1; i++) {
// set real part
re[i] = fft[i * 2 - 1];
// set imaginary part
im[i] = fft[i * 2 - 2];
// Calculate magnitude
mg[i] = Math.sqrt(re[i] * re[i] + im[i] * im[i]);
}
re[i] = fft[fft.length - 1];
im[i] = 0;
mg[i] = Math.sqrt(re[i] * re[i]);
for (i = 1; i < mg.length; i++) {
if (mg[i] > mg[mgIndex])
mgIndex = i;
}
return mgIndex * sampleRate / blockSize;
}
/**
*
* @reference
* http://stackoverflow.com/questions/11600515/hanning-von-hann
* -window
* @param signal_in
* @param pos
* @param size
*/
public void HanningWindow(double[] signal_in, int pos, int size) {
for (int i = pos; i < pos + size; i++) {
int j = i - pos; // j = index into Hann window function
signal_in[i] = signal_in[i] * 0.5
* (1.0 - Math.cos(2.0 * Math.PI * j / size));
}
}
}