【发布时间】:2014-12-27 23:51:24
【问题描述】:
我想从任何 Android 设备获取超声波,例如频率在 18KHz 和 19KHz 之间的超声波。
我使用下面的代码来计算频率,但它似乎没有让我得到正确的频率。我得到的频率保持在 11 KHz 和 13KHz 之间。
private void calculateFrequency()
{
// 1 - Initialize audio
int channel_config = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int format = AudioFormat.ENCODING_PCM_16BIT;
int sampleRate = 8000;
int bufferSize = 2048;
if (bufferSize < AudioRecord.getMinBufferSize(sampleRate, channel_config, format))
bufferSize = AudioRecord.getMinBufferSize(sampleRate, channel_config, format);
AudioRecord audioInput = new AudioRecord(AudioSource.MIC, sampleRate, channel_config, format, bufferSize);
// 2 - Get sound
byte[] audioBuffer = new byte[bufferSize];
audioInput.startRecording();
int nbRead = audioInput.read(audioBuffer, 0, bufferSize);
audioInput.stop();
audioInput.release();
// 3 - Transform to double array
double[] micBufferData = new double[bufferSize];
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 < nbRead - 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;
}
// 4 - Create complex array
Complex[] fftTempArray = new Complex[bufferSize];
for (int i=0; i<bufferSize; i++)
{
fftTempArray[i] = new Complex(micBufferData[i], 0);
}
// 5 - Calculate FFT
Complex[] fftArray = FFT.fft(fftTempArray);
// 6 - Calculate magnitude
double[] magnitude = new double[bufferSize / 2];
for (int i = 0; i < (bufferSize / 2); i++)
{
magnitude[i] = Math.sqrt(fftArray[i*2].re() * fftArray[i*2].re() + fftArray[i*2].im() * fftArray[i*2].im());
}
// 7 - Get maximum magnitude
double max_magnitude = -1;
for (int i = 0; i < bufferSize / 2; i++)
{
if (magnitude[i] > max_magnitude)
{
max_magnitude = magnitude[i];
}
}
// 8 - Calculate frequency
int freq = (int)(max_magnitude * sampleRate / bufferSize);
((TextView) findViewById(R.id.textView1)).setText("FREQUENCY = " + freq + "Hz");
}
我正在使用两部手机:一部使用this app 发送超声波,另一部用于获取超声波。 我使用这个question 作为我学习 FFT 和 Complex 类的起点。
我的代码有什么问题?
【问题讨论】:
-
好主意。你能帮我解释一下吗:
int freq = (int)(max_magnitude * sampleRate / bufferSize);. -
我用了这个答案link:见最后一行代码
-
错误出现在第 7 步和第 8 步中 - 您需要最大幅度的 index 来确定频率,而不是幅度本身。仔细看看链接答案中的伪代码。
-
您的采样率必须超过每个 nyquist 感兴趣频率的两倍。
-
你如何修复幅度指数中的错误值?它有时像 i = max_length_of_magnitude 和频率中的值 = 46000+
标签: java android signal-processing fft audiorecord