【发布时间】:2016-08-26 02:17:20
【问题描述】:
我正在尝试实现一个应用程序,即使存在环境背景噪音,我也可以检测到特定频率(1000Hz - 1500Hz)的哨声,并且在网上进行了大量研究之后,我使用了 FFT 方法尝试检测从麦克风捕获的最大幅度是否与哨音频率相对应。
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);
}
}
});
}
我已经设置了一个麦克风录音机等等,但我不明白代码在做什么,而且我收到一些错误,说我的 fftarray 是负数。有人可以帮我指出正确的方向吗?还是有更好的方法来实现哨子检测?我正在使用来自here 的代码。我得到一个 N 不是抛出 2 个异常的力量。
【问题讨论】:
-
你不明白代码在做什么是什么意思?不是你的吗?
-
如果您想确定声音中是否存在特定频率,那么 FFT 是正确的方法。你的问题到底是什么?
-
我在尝试运行代码时遇到了一些错误。我得到 java.lang.RuntimeException: N is not a power of 2 for final Complex[] fftArray = FFT.fft(fftTempArray);
-
这种东西最好先用更高级的语言(mathematica、matlab、python-numpy)做原型来整理数学。对于 numpy 中的带通,请参见例如stackoverflow.com/questions/36968418/…
标签: java android android-studio fft