首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用频率从android中获取超声波

使用频率从android中获取超声波
EN

Stack Overflow用户
提问于 2014-10-31 15:40:02
回答 2查看 2K关注 0票数 4

我想从任何Android设备中得到超声波,例如,频率在18 and到19 and之间的超声波。

我使用下面的代码计算频率,但似乎没有得到正确的频率。我的频率停留在11 KHz到13 KHz之间。

代码语言:javascript
复制
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");
}

我用了两部手机:一部用这个应用程序发送超声波,另一部用来获取超声波。我使用这个问题作为起点,在这里我使用了、FFT、复杂类。

我的密码怎么了?

EN

回答 2

Stack Overflow用户

发布于 2014-10-31 19:10:34

为了得到正确的非混叠频率估计,一个人必须使用比音频输入中最高频率的两倍更多的采样率(为了避免滤波器的滚动,可能要高出10%到20% ),从而超过你想要找到的最高频率的两倍。

这是由于抽样定理所要求的奈奎斯特速率。

因此,如果你想找到一个19 kHz信号,一个接近48000的采样率是必需的。

票数 4
EN

Stack Overflow用户

发布于 2014-11-01 08:46:22

步骤7和步骤8并不完全正确,您需要使用具有最大震级的FFT桶的索引来确定频率:

代码语言:javascript
复制
    // 7 - Get maximum magnitude
    double max_magnitude = -1;
    int max_magnitude_index = -1;
    for (int i = 0; i < bufferSize / 2; i++)
    {
        if (magnitude[i] > max_magnitude)
        {
            max_magnitude = magnitude[i];
            max_magnitude_index = i;
        }
    }

    // 8 - Calculate frequency
    int freq = (int)(max_magnitude_imdex * sampleRate / bufferSize);

正如@hotpaw2所指出的,8 kHz的采样率太低了--至少需要44.1 kHz,最好是48 kHz。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26678407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档