开发者

How do I implement a bandpass filter in C (Purpose: pitch detection)?

开发者 https://www.devze.com 2023-01-23 09:39 出处:网络
I recently asked this question: I am looking for an algorithm to detect pitch.one of the answers suggested thatI use an initial FFTto get the basic frequency response,figure out which frequencies are

I recently asked this question:

I am looking for an algorithm to detect pitch. one of the answers suggested that I use an initial FFT to get the basic frequency response, figure out which frequencies are getting voiced, and follow it up with a band pass filter in each area of interest:

A slightly advanced algorithm could do something like this:

  1. Roughly detect pitch frequency (could be done with DFT).
  2. Bandpass signal to filter isolate pitch frequency.
  3. Count the number of samples between two peaks in the filtered signals.

Now I can do the first step okay ( I am coding for iOS, and Apple has a framework (the accelerate framework) for doing FFTs etc.

I have made a start here: but I can see the problem: an FFT that would differentiate all of the possible notes one could sing would require a lot of samples, and I don't want to perform too much unnecessary computation as I'm targeting a mobile device.

So I'm trying to get my head round this answer above, but I don't understand how I cou开发者_JAVA技巧ld apply the concept of a band pass filter to code.

Can anyone help?


Filter design is pretty complex. There are many techniques. First you have to decide what kind of filter you want to create. Finite impulse response (FIR)? Infinite impulse response (IIR)? Then you select an algorithm for designing a filter of that type. The Remez algorithm is often used for FIR filter design. Go here to see the complexity that I was referring to: http://en.wikipedia.org/wiki/Remez_algorithm

Your best best for creating a filter is to use an existing signal processing library. A quick Google search led me here: http://spuc.sourceforge.net/

Given what your application is, you may want to read about matched filters. I am not sure if they are relevant here, but they might be. http://en.wikipedia.org/wiki/Matched_filter


well in Wikipedia, checkup on low-pass filter, and hi-pass, then join them to make a band-pass filter. Wikipedia has code implementations for those two filters.

http://en.wikipedia.org/wiki/Low-pass_filter http://en.wikipedia.org/wiki/High-pass_filter


Since you only want to detect a single frequency, it would be an overkill to perform a DFT to then only use one of the values.

You could implement the Goertzel algorithm. Like this C implementation used to detect DTMF tones over a phone line, from the FreePBX source code:

float goertzel(short x[], int nmax, float coeff) {
    float s, power;
    float sprev, sprev2;
    int   n;

    sprev = 0;
    sprev2 = 0;
    for(n=0; n<nmax; n++) {
        s = x[n] + coeff * sprev - sprev2;
        sprev2 = sprev;
        sprev = s;
    }

    power = sprev2*sprev2 + sprev*sprev - coeff*sprev*sprev2;

    return power;
}

As you can see, the implementation is fairly trivial and quite effective for single frequencies. Check the link for different versions with and without floating point, and how to use it.

0

精彩评论

暂无评论...
验证码 换一张
取 消