java– 使用频率从android获取超声波

java– 使用频率从android获取超声波,第1张

概述我希望从任何Android设备获得超声波,例如频率介于18KHz和19KHz之间的超声波.我使用下面的代码来计算频率,但它似乎没有让我得到正确的频率.我的频率保持在11KHz和13KHz之间.privatevoidcalculateFrequency(){//1-Initializeaudiointchannel_config=

我希望从任何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和复杂类.

我的代码出了什么问题?

解决方法:

为了获得正确的非混叠频率估计,必须使用更多的采样率(可能比滤波器滚降更大10%到20%),而不是音频输入中最高频率的两倍,因此超过两倍你想要找到的最高频率.

这是由于采样定理所需的奈奎斯特速率.

因此,如果要查找19 kHz信号,则需要接近48000的采样率.

总结

以上是内存溢出为你收集整理的java – 使用频率从android获取超声波全部内容,希望文章能够帮你解决java – 使用频率从android获取超声波所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1113366.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存