【问题标题】:Android: fundamental frequencyAndroid:基频
【发布时间】:2014-07-15 02:15:30
【问题描述】:

我想在 Android 应用程序中找到人声的基频。我正在用this FFT class 和这个Complex class 计算这个。

我计算 FFT 的代码是这样的:

public double calculateFFT(byte[] signal)
        {           
        final int mNumberOfFFTPoints =1024;
        double mMaxFFTSample;

        double temp;
        Complex[] y;
        Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
        double[] absSignal = new double[mNumberOfFFTPoints/2];

        for(int i = 0; i < mNumberOfFFTPoints; i++){
            temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
            complexSignal[i] = new Complex(temp,0.0);
        }

        y = FFT.fft(complexSignal); 

        mMaxFFTSample = 0.0;
        int mPeakPos = 0;
        for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
        {
            absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));

            if(absSignal[i] > mMaxFFTSample)
            {
                mMaxFFTSample = absSignal[i];
                mPeakPos = i;
            } 
        }


        return ((1.0 * sampleRate) / (1.0 * mNumberOfFFTPoints)) * mPeakPos;

    }

我的价值观与 How do I obtain the frequencies of each value in an FFT?

是否可以从这些值中找到基频?有人可以帮我吗?

提前致谢。

【问题讨论】:

标签: java android fft frequency pitch


【解决方案1】:

听起来您已经为您的问题选择了解决方案 (FFT)。我不是 DSP 专家,但我敢打赌,您不会以这种方式获得很好的结果。在此处查看更详细的讨论:How do you analyse the fundamental frequency of a PCM or WAV sample?

如果你确实选择坚持这种方法:

  1. 如果您需要较低频率的准确度,请考虑使用超过 1024 个点 - 请记住(口语)human voice is surprisingly low

  2. 明智地选择采样频率 - 如果可以,请应用 low-pass filter。电话的带宽只有约 3KHz 是有原因的,其余的对于听到人类的声音并不是真正必要的。

  3. 然后,检查输出值的前半部分,并选择 最大的一个:这是最难的部分 - 可能有几个(更多的峰值应该出现在这也是谐波(固定倍数),但这很难检查,因为你的桶在这里没有有用的大小)。这是真正的基频希望所在的频率范围。

同样,也许值得考虑解决此问题的其他方法,因为 FFT 在现实世界中可能会给您带来令人失望的结果。

【讨论】:

  • 我尝试用 edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D 找到具有自相关的基频;但不知道返回frequency=sampleRate*double)max_index/(double)mNumberOfFFTPoints;}的值是不是基频?
【解决方案2】:

我的自相关代码:

    public double calculateFFT(double[] signal)

     {
      final int mNumberOfFFTPoints =1024;

      double[] magnitude = new double[mNumberOfFFTPoints/2];
      DoubleFFT_1D fft = new DoubleFFT_1D(mNumberOfFFTPoints);
      double[] fftData = new double[mNumberOfFFTPoints*2];
      double max_index=-1;
      double max_magnitude=-1;


      final float sampleRate=44100;
      double frequency;

      for (int i=0;i<mNumberOfFFTPoints;i++){

       //fftData[2 * i] = buffer[i+firstSample];
       fftData[2 * i] = signal[i];  //da controllare
       fftData[2 * i + 1] = 0;

       fft.complexForward(fftData);
      }

      for(int i = 0; i < mNumberOfFFTPoints/2; i++){

       magnitude[i]=Math.sqrt((fftData[2*i] * fftData[2*i]) + (fftData[2*i + 1] * fftData[2*i + 1]));



       if (max_magnitude<magnitude[i]){
        max_magnitude=magnitude[i];
        max_index=i;
       }
      }


      return frequency=sampleRate*(double)max_index/(double)mNumberOfFFTPoints;

 }

“返回”的值是我的基频?

【讨论】:

  • 有些情况下不能!
  • 为什么?我注意到 fft.complexForward(fftData) 不起作用,我不知道,因为会发生这种情况。
【解决方案3】:

FFT 最大值返回峰值 bin 频率,它可能不是基频,而是 FFT 结果 bin 最接近基频的泛音或谐波。使用更多数据的较长 FFT 将为您提供更紧密间隔的 FFT 结果箱,因此箱可能更接近峰值频率。如果峰值位于 bin 之间,您也可以对其进行插值。但是,如果您要处理具有强谐波成分的信号,例如语音或音乐,您可能需要使用音高检测/估计算法而不是 FFT 峰值算法。

【讨论】:

【解决方案4】:

人声的基频检测是一个活跃的研究领域,如下面的参考资料所示。您的方法必须经过精心设计,并且必须取决于数据的性质。

例如,如果您的音源是一个唱单个音符的人,而录音中没有音乐或其他背景声音,则修改后的峰值检测器可能会提供合理的结果。

如果您的源是广义的人类语音,那么除了语音中的各个共振峰之外,您将无法获得唯一的基本频率。

下图说明了一个简单的检测问题。它显示了持有降 B-3 (Bb3) 音符的女高音的频谱。 Bb3 的基频是 233 Hz,但女高音实际上唱的是 236 Hz 基频(最左边和最高峰)。在这种情况下,简单的峰值检测器会产生正确的基频。

下图说明了基频检测的挑战之一,即使是单独演唱的音符,更不用说广义的人类语音了。它显示了拿着 F4 音符的女高音的频谱。 F4 的基频是 349 Hz,但女高音实际上唱的是 360 Hz 基频(最左边的峰值)。

但是,在这种情况下,最高峰不是基波,而是 714 Hz 的一次谐波。您修改后的峰值检测器将不得不应对这些情况。

在广义的人类语音中,基本频率的概念并不真正适用于持续时间比语音中每个单独共振峰更长的任何子集。这是因为广义人类语音的频谱是高度时变的。

请参阅这些参考资料:

Speech Signal Analysis

Human Speech Formants

Fundamental frequency detection

来自Sooeet.com FFT calculator的FFT、图表和音频数据

【讨论】:

    猜你喜欢
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 2014-10-14
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多