【问题标题】:How to calculate frequency level from audio recorder mic input data如何从录音机麦克风输入数据计算频率电平
【发布时间】:2017-06-28 11:09:00
【问题描述】:

我正在 android 中做声音分析器应用程序。我可以使用 AudioTrack Api 生成 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);
}

}

这是我的输出。请让我知道我在哪里做错了。

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。但我没有得到我的频率。如何过滤我的频率。谢谢。

【问题讨论】:

  • 在此处删除(int) 演员表:max_magnitude = (int) magnitude[i]; - 可能还有其他问题,但这绝对是错误的。另请注意,大多数设备在 > 18 kHz 时的灵敏度非常差 - 麦克风通常在 15 kHz 以上时响应较差,抗混叠滤波器也可能进一步降低电平。
  • @Paul R 感谢您的回复,我删除(int)。但它不起作用,我生成 14 khz 频率但我没有得到。这是我的日志结果 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
  • 什么是窗口函数?怎么做?
  • 尝试绘制您的时域波形和频谱,看看它们是否合理——这通常是缩小问题范围的好方法。对于窗口函数,您只需search here on StackOverflow 和/或阅读Wikipedia entry

标签: android audio fft audio-recording arduino-ultra-sonic


【解决方案1】:

查看我的示例项目。 :DGithub.

此检索频率具有高精度和高速度,基于 Google 开发人员开发的 Spectrum Analyzer 应用程序。

【讨论】:

    【解决方案2】:

    最后我找到了答案。只需在我的代码中应用 FFT 而不是 JTransforms lib。此代码对我有用。

    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)        
    
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    相关资源
    最近更新 更多