如何进行语音频率检测?

Posted

技术标签:

【中文标题】如何进行语音频率检测?【英文标题】:how to voice frequency detect? 【发布时间】:2012-04-13 08:43:27 【问题描述】:

我是初学者 android 程序员。 (我的母语不是英语,所以我的英语很差。)

我想制作应用程序,获取频率记录的人声并显示“C3”或“G#4”之类的音符......

所以,我想检测人声频率,但是太难了。

我尝试使用 FFT,它检测到钢琴(或吉他)的声音非常好(某些部分,超过 octave4,它没有检测到低频钢琴(或吉他)的声音。),但它无法检测到人声。

(我使用钢琴程序使用一般的midi)

查了很多资料,但看不懂。

大多数人说使用音高检测算法并仅链接 wiki。

请详细告诉我音高检测算法。

(其实我想要示例代码:(

有什么想法可以使用我的应用吗?

这是我的源代码:

 public void Frequency(double[] array) 

    int sampleSize = array.length;  

    double[] win = window.generate(sampleSize);

    // signals for fft input
    double[] signals = new double[sampleSize];
    for (int i = 0; i < sampleSize; i++) 
        signals[i] = array[i] * win[i];
    
    double[] fftArray = new double[sampleSize * 2];

    for (int i = 0; i < sampleSize - 1; i++) 
        fftArray[2 * i] = signals[i];
        fftArray[2 * i + 1] = 0;
    


    FFT.complexForward(fftArray);
    getFrequency(fftArray);


private void getFrequency(double[] array) 

    // ========== Value ========== //

    int RATE = sampleRate;
    int CHUNK_SIZE_IN_SAMPLES = RECORDER_BUFFER_SIZE;
    int MIN_FREQUENCY = 50; // HZ
    int MAX_FREQUENCY = 2000; // HZ

    int min_frequency_fft = Math.round(MIN_FREQUENCY * CHUNK_SIZE_IN_SAMPLES / RATE);
    int max_frequency_fft = Math.round(MAX_FREQUENCY * CHUNK_SIZE_IN_SAMPLES / RATE);
    // ============================ //

    double best_frequency = min_frequency_fft;
    double best_amplitude = 0;
    for (int i = min_frequency_fft; i <= max_frequency_fft; i++) 

        double current_frequency = i * 1.0 * RATE / CHUNK_SIZE_IN_SAMPLES;

        double current_amplitude = Math.pow(array[i * 2], 2) + Math.pow(array[i * 2 + 1], 2);

        double normalized_amplitude = current_amplitude * Math.pow(MIN_FREQUENCY * MAX_FREQUENCY, 0.5) / current_frequency;

        if (normalized_amplitude > best_amplitude) 
            best_frequency = current_frequency;
            best_amplitude = normalized_amplitude;
        
    

    FrequencyArray[FrequencyArrayIndex] = best_frequency;
    FrequencyArrayIndex++;

我指的是这个:http://code.google.com/p/android-guitar-tuner/

Pitch_detection_algorithm

使用 Jtransforms

【问题讨论】:

您发布的代码仅适用于简单的声音,例如正弦波。真实的声音通常要复杂得多。 "请详细告诉我音高检测算法。"网上有很多关于音高检测的信息。如果你不能理解(这里没有冒犯的意思,有些事情只是需要大量的专业背景才能理解),我们如何以你能理解的方式向你描述呢? SO 是一个编程问答网站,并不是真正适合此类问题的论坛。 【参考方案1】:

关于音高检测的***页面链接到另一个解释自相关的***页面:http://en.m.wikipedia.org/wiki/Autocorrelation#section_3,这是您可以尝试的众多音高估计方法之一。

运行您发布的示例代码可以表明,FFT 峰值频率估计在音高检测和许多常见音高的估计方面非常差。

【讨论】:

以上是关于如何进行语音频率检测?的主要内容,如果未能解决你的问题,请参考以下文章

Matlab:在一帧音频数据中查找主要频率

如何使用 Goertzel 算法检测频率

语音中的关于语音识别的一些知识

VB.net现场频率检测

检测特定频率和持续时间的哔声

iPhone:检测特定频率(幅度)的复制声音