Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 利用Goertzel算法进行频率检测_Java_Android_Signal Processing_Goertzel Algorithm - Fatal编程技术网

Java 利用Goertzel算法进行频率检测

Java 利用Goertzel算法进行频率检测,java,android,signal-processing,goertzel-algorithm,Java,Android,Signal Processing,Goertzel Algorithm,我正在尝试为android编写一个程序,使用Goertzel算法检测频率。但是,当我对从AudioRecord read()方法获得的数据应用该算法时,幅值不会在目标频率上达到峰值(.e:它通常在低频率上达到峰值)。我有什么误解吗 protected void detect() { double[] dbSample = new double[bufferSize]; short[] sample = new short[bufferSize];

我正在尝试为android编写一个程序,使用Goertzel算法检测频率。但是,当我对从AudioRecord read()方法获得的数据应用该算法时,幅值不会在目标频率上达到峰值(.e:它通常在低频率上达到峰值)。我有什么误解吗

protected void detect() {
        double[] dbSample = new double[bufferSize];
        short[] sample = new short[bufferSize];
        max_magnitude = 0;
        while(isRecording){
            int bufferReadResult = recorder.read(sample,0,bufferSize);
            for (int j=0;j<bufferSize&&j<bufferReadResult;j++) {
                dbSample[j] = (double)sample[j];
            }
        }     

        int freq=0;
        while(freq<=20000){
            Goertzel g = new Goertzel(RECORDER_SAMPLE_RATE,freq,bufferSize);
            g.initGoertzel();
            for(int i=0;i<bufferSize;i++){
                g.processSample(dbSample[i]);
            }
            magnitude = Math.sqrt(g.getMagnitudeSquared());
            if(magnitude>max_magnitude){
                max_magnitude = magnitude;
                detect_freq = freq;
            }
            g.resetGoertzel();
            freq+=50;
        }
}

}

为了澄清,您期望的缓冲区大小和目标频率是多少?将有一个发射机(使用matlab生成音调的笔记本电脑),该程序必须检测发射机的频率。对于缓冲区大小,我使用getMinBufferSize(44100,AudioFormat.CHANNEL\u CONFIGURATION\u MONO,AudioFormat.ENCODING\u PCM\u 16位);如果我正确理解了你的代码,你正在以50 Hz的增量扫过0到20 kHz的频率,并计算滤波器响应,而峰值响应并不是你所期望的。这与其说是音调检测,不如说是频谱分析仪。你能画出滤波器响应图并显示目标频率应该在哪里吗?对不起,我只是个学生,这是我的作业,所以我不是android编程方面的专家,而且这对我来说是全新的。如果您不介意的话,请您解释一下如何使用goertzel检测音调?我写这段代码是因为我在网上发现,目标频率通常返回goertzel()的峰值幅值。我是否误解了什么,因为这个代码似乎不起作用,而且它的响应也不一致。对于音调检测,您试图检测信号中是否存在一个特定频率。对于频谱分析,您试图确定信号在不同频率下的响应。你想解决哪个问题?
public class Goertzel {
 private float samplingRate;
 private float targetFrequency;
 private long n;
 private double coeff, Q1, Q2;
 private double sine, cosine;

 public Goertzel(float samplingRate, float targetFrequency, long inN) {
     this.samplingRate = samplingRate;
     this.targetFrequency = targetFrequency;
     n = inN;
     sine = Math.sin(2 * Math.PI * (targetFrequency / samplingRate));
     cosine = Math.cos(2 * Math.PI * (targetFrequency / samplingRate));
     coeff = 2 * cosine;
     }

     public void resetGoertzel() {
     Q1 = 0;
     Q2 = 0;
 }

 public void initGoertzel() {
     int k;
     float floatN;
     double omega;
     floatN = (float) n;
     k = (int) (0.5 + ((floatN * targetFrequency) / samplingRate));
     omega = (2.0 * Math.PI * k) / floatN;
     sine = Math.sin(omega);
     cosine = Math.cos(omega);
     coeff = 2.0 * cosine;
     resetGoertzel();
 }

 public void processSample(double sample) {
     double Q0;
     Q0 = coeff * Q1 - Q2 + sample;
     Q2 = Q1;
     Q1 = Q0;
 }

 public double[] getRealImag(double[] parts) {
     parts[0] = (Q1 - Q2 * cosine);
     parts[1] = (Q2 * sine);
     return parts;
 }

 public double getMagnitudeSquared() {
     return (Q1 * Q1 + Q2 * Q2 - Q1 * Q2 * coeff);
 }