Java – get ultrasound from Android using frequency

I want to get ultrasound from any Android device, such as ultrasound with a frequency between 18khz and 19khz

I use the following code to calculate the frequency, but it doesn't seem to get me the correct frequency My frequency remains between 11 kHz and 13 kHz

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,format);
    AudioRecord audioInput = new AudioRecord(AudioSource.MIC,sampleRate,format,bufferSize);

    // 2 - Get sound
    byte[] audioBuffer = new byte[bufferSize];
    audioInput.startRecording();
    int nbRead = audioInput.read(audioBuffer,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");
}

I am using two mobile phones: one uses this app to send ultrasound, and the other is for ultrasound I use this question as a starting point. I use FFT and complex classes

What's wrong with my code?

Solution

In order to obtain a correct non aliasing frequency estimation, you must use more sampling rates (possibly 10% to 20% greater than the filter roll off), rather than twice the highest frequency in the audio input, so more than twice the highest frequency you want to find

This is due to the Nyquist rate required by the sampling theorem

Therefore, if you want to find a 19 kHz signal, you need a sampling rate close to 48000

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>