Detect a specific frequency/tone from raw wave-data

前端 未结 6 1949
天涯浪人
天涯浪人 2020-12-03 04:03

I am reading a raw wave stream coming from the microphone.
(This part works as I can send it to the speaker and get a nice echo.)

For simplicity lets say I want

相关标签:
6条回答
  • 2020-12-03 04:22

    I found this as a simple implementation of Goertzel. Haven't gotten it to work yet (looking for wrong frequency?), but I thought I'd share it anywas. It is copied from this site.

            public static double CalculateGoertzel(byte[] sample, double frequency, int samplerate)
            {
                double Skn, Skn1, Skn2;
                Skn = Skn1 = Skn2 = 0;
                for (int i = 0; i < sample.Length; i++)
                {
                    Skn2 = Skn1;
                    Skn1 = Skn;
                    Skn = 2 * Math.Cos(2 * Math.PI * frequency / samplerate) * Skn1 - Skn2 + sample[i];
                }
                double WNk = Math.Exp(-2 * Math.PI * frequency / samplerate);
                return 20 * Math.Log10(Math.Abs((Skn - WNk * Skn1)));
            }
    
    0 讨论(0)
  • 2020-12-03 04:26

    Let's say that typical DTMF frequency is 200Hz - 1000Hz. Then you'd have to detect a signal based on between 4 and 20 cycles. FFT will not get you anywhere I guess, since you'll detect only multiples of 50Hz frequencies: this is a built in feature of FFT, increasing the number of samples will not solve your problem. You'll have to do something more clever.

    Your best shot is to linear least-square fit your data to

    h(t) = A cos (omega t) + B sin (omega t)
    

    for a given omega (one of the DTMF frequencies). See this for details (in particular how to set a statistical significance level) and links to the litterature.

    0 讨论(0)
  • 2020-12-03 04:27

    Very nice implementation of Goertzel is there. C# modification:

    private double GoertzelFilter(float[] samples, double freq, int start, int end)
        {
            double sPrev = 0.0;
            double sPrev2 = 0.0;
            int i;
            double normalizedfreq = freq / SIGNAL_SAMPLE_RATE;
            double coeff = 2 * Math.Cos(2 * Math.PI * normalizedfreq);
            for (i = start; i < end; i++)
            {
                double s = samples[i] + coeff * sPrev - sPrev2;
                sPrev2 = sPrev;
                sPrev = s;
            }
            double power = sPrev2 * sPrev2 + sPrev * sPrev - coeff * sPrev * sPrev2;
            return power;
        }
    

    Works great for me.

    0 讨论(0)
  • 2020-12-03 04:30

    Spectral Analysis.

    All application where you extract frequencies from signals goes under field spectral analysis.

    0 讨论(0)
  • 2020-12-03 04:32

    As far as any .NET libraries that do this try TAPIEx ToneDecoder.Net Component. I use it for detecting DTMF, but it can do custom tones as well.

    I know this question is old, but maybe it will save someone else several days of searching and trying out code samples and libraries that just don't work.

    0 讨论(0)
  • 2020-12-03 04:33

    You may want to look at the Goertzel algorithm if you're trying to detect specific frequencies such as DTMF input. There is a C# DTMF generator/detector library on Sourceforge based on this algorithm.

    0 讨论(0)
提交回复
热议问题