AndroidaudioFFT使用audiorecord检索特定的频率大小
我目前正在尝试使用Android来实现一些代码,以检测通过手机麦克风播放多个特定audio范围的时间。 我已经使用AudioRecord
类设置了类:
int channel_config = AudioFormat.CHANNEL_CONFIGURATION_MONO; int format = AudioFormat.ENCODING_PCM_16BIT; int sampleSize = 8000; int bufferSize = AudioRecord.getMinBufferSize(sampleSize, channel_config, format); AudioRecord audioInput = new AudioRecord(AudioSource.MIC, sampleSize, channel_config, format, bufferSize);
然后读入audio:
short[] audioBuffer = new short[bufferSize]; audioInput.startRecording(); audioInput.read(audioBuffer, 0, bufferSize);
执行FFT是我陷入困境的地方,因为我在这方面的经验很less。 我一直在尝试使用这个类:
在Java和复杂类的 FFT 与它一起去
然后我发送以下值:
Complex[] fftTempArray = new Complex[bufferSize]; for (int i=0; i<bufferSize; i++) { fftTempArray[i] = new Complex(audio[i], 0); } Complex[] fftArray = fft(fftTempArray);
这可能很容易让我误解这个class级是如何工作的,但是这个价值观又回到了原来的位置,即使在沉默中也不能代表一致的频率。 有没有人知道一个方法来执行这个任务,或者我是过于复杂的事情,试图抓住less量的频率范围,而不是把它作为一个graphics表示?
首先你需要确保你得到的结果被正确地转换成float / double。 我不确定short []版本是如何工作的,但byte []版本只返回原始字节版本。 这个字节数组然后需要被正确地转换成一个浮点数。 转换的代码应该是这样的:
double[] micBufferData = new double[<insert-proper-size>]; final int bytesPerSample = 2; // As it is 16bit PCM final double amplification = 100.0; // choose a number as you like for (int index = 0, floatIndex = 0; index < bytesRecorded - bytesPerSample + 1; index += bytesPerSample, floatIndex++) { double sample = 0; for (int b = 0; b < bytesPerSample; b++) { int v = bufferData[index + b]; if (b < bytesPerSample - 1 || bytesPerSample == 1) { v &= 0xFF; } sample += v << (b * 8); } double sample32 = amplification * (sample / 32768.0); micBufferData[floatIndex] = sample32; }
然后你使用micBufferData []来创build你的input复数组。
一旦得到结果,使用结果中复数的大小。 除了具有实际值的频率之外,大部分幅度应该接近于零。
您需要采样频率来将arrays索引转换为如下的频率:
private double ComputeFrequency(int arrayIndex) { return ((1.0 * sampleRate) / (1.0 * fftOutWindowSize)) * arrayIndex; }