如何计算音频记录器麦克风输入数据的频率水平
问题描述:
我在android.I中做声音分析器应用程序可以使用AudioTrack Api.i生成18 kHz至20 kHz超声波音频可以使用AudioRecord Api记录音频。但我不能知道如何计算麦克风输入数据的频率。我看到了多个问题How to get frequency from fft result?和Get frequency wav audio using FFT and Complex class它没有给出正确的频率。请帮助我。谢谢我的沟通。如何计算音频记录器麦克风输入数据的频率水平
这是我的频率计算代码
int bufferSizeInBytes = 1024;
short[] buffer = new short[bufferSizeInBytes];
class Recording extends Thread {
@Override
public void run() {
while (true) {
bufferReadResult = audioInput.read(buffer, 0, bufferSizeInBytes); // record data from mic into buffer
if(bufferReadResult > 0){
calculate();
}
}
}
public void calculate() {
DoubleFFT_1D fft1d = new DoubleFFT_1D(bufferSizeInBytes);//using JTransforms lib
double[] fftBuffer = new double[bufferSizeInBytes * 2];
double[] magnitude = new double[bufferSizeInBytes/2];
// copy real input data to complex FFT buffer
for (int i = 0; i < bufferSizeInBytes - 1; ++i) {
fftBuffer[2 * i] = buffer[i];
fftBuffer[2 * i + 1] = 0;
}
//perform FFT on fft[] buffer
fft1d.realForward(fftBuffer);
// calculate power spectrum (magnitude) values from fft[]
for (int i = 0; i < (bufferSizeInBytes/2) - 1; ++i) {
double real = fftBuffer[2 * i];
double imaginary = fftBuffer[2 * i + 1];
magnitude[i] = Math.sqrt(real * real + imaginary * imaginary);
}
// find largest peak in power spectrum
double max_magnitude = magnitude[0];
int max_index = 0;
for (int i = 0; i < magnitude.length; ++i) {
if (magnitude[i] > max_magnitude) {
max_magnitude = (int) magnitude[i];
max_index = i;
}
}
double freq = max_index * 44100/bufferSizeInBytes;
Log.e("AudioBEacon", "" + freq);
}
}
这是我output.Please让我知道我做了错误。
02-10 12:33:04.450 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21662.0
02-10 12:33:04.451 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21317.0
02-10 12:33:04.453 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21791.0
02-10 12:33:04.471 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21748.0
02-10 12:33:04.472 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21533.0
02-10 12:33:04.474 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21834.0
02-10 12:33:04.491 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21533.0
02-10 12:33:04.493 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21705.0
02-10 12:33:04.511 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21533.0
02-10 12:33:04.512 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21447.0
02-10 12:33:04.513 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21490.0
02-10 12:33:04.531 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21576.0
02-10 12:33:04.551 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21619.0
02-10 12:33:04.591 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21877.0
02-10 12:33:04.613 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21576.0
02-10 12:33:04.633 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21920.0
02-10 12:33:04.653 17013-17063/com.org.sohamsaa.audiobeacontransmitter E/AudioBEacon: 21791.0
我的频率范围为18 kHz至20 khz.but我没有得到我的frequency.how筛选我frequency.thank你。
答
最后我找到了答案。只需在我的代码中应用FFT而不是JTransforms库。此代码适用于我。
int bufferSizeInBytes = 1024;
short[] buffer = new short[bufferSizeInBytes];
class Recording extends Thread {
@Override
public void run() {
while() {
if (true) {
int bufferReadResult = audioInput.read(buffer, 0, bufferSizeInBytes); // record data from mic into buffer
if (bufferReadResult > 0) {
calculate();
}
}
}
}
}
public void calculate() {
double[] magnitude = new double[bufferSizeInBytes/2];
//Create Complex array for use in FFT
Complex[] fftTempArray = new Complex[bufferSizeInBytes];
for (int i = 0; i < bufferSizeInBytes; i++) {
fftTempArray[i] = new Complex(buffer[i], 0);
}
//Obtain array of FFT data
final Complex[] fftArray = FFT.fft(fftTempArray);
// calculate power spectrum (magnitude) values from fft[]
for (int i = 0; i < (bufferSizeInBytes/2) - 1; ++i) {
double real = fftArray[i].re();
double imaginary = fftArray[i].im();
magnitude[i] = Math.sqrt(real * real + imaginary * imaginary);
}
// find largest peak in power spectrum
double max_magnitude = magnitude[0];
int max_index = 0;
for (int i = 0; i < magnitude.length; ++i) {
if (magnitude[i] > max_magnitude) {
max_magnitude = (int) magnitude[i];
max_index = i;
}
}
double freq = 44100 * max_index/bufferSizeInBytes;//here will get frequency in hz like(17000,18000..etc)
}
删除'(INT)'投这里:'max_magnitude =(int)的大小[I]' - 可能还有其他的问题,但是这肯定是不对的。还要注意,大多数设备在> 18 kHz时的灵敏度非常差 - 麦克风通常在15 kHz以上响应较差,抗干扰滤波器可能会进一步降低音量。 –
@保罗 - [R感谢您的回复,我删除(INT),但它不工作,我产生14 kHz的频率,但我不getting.This是我的日志结果 E/AudioBEacon:861.0 E/AudioBEacon: 21404.0 E/AudioBEacon:21705.0 E/AudioBEacon:21447.0 E/AudioBEacon:215.0 E/AudioBEacon:21705.0 E/AudioBEacon:344.0 E/AudioBEacon:473.0 E/AudioBEacon:430.0 – Siddharthan
是什么窗函数怎么做? – Siddharthan