Domanda

Sto leggendo un flusso d'onda prima proveniente dal microfono.
(Questa parte funziona come posso inviare al diffusore ed ottenere una bella eco.)

Per semplicità consente di dire che voglio rilevare un DTMF tono nei dati onda. In realtà voglio rilevare qualsiasi frequenza, non solo quelli in DTMF. Ma ho sempre sapere quale frequenza Sto cercando.

Ho provato a fare funzionare attraverso FFT, ma non sembra molto efficiente se voglio elevata precisione nella rilevazione (dire che è lì solo per 20 ms). Posso rilevare in giù con una precisione di circa 200 ms.

Quali sono le opzioni per quanto riguarda gli algoritmi? Ci sono tutte le librerie .Net per questo?

È stato utile?

Soluzione

Si consiglia di guardare il Goertzel algoritmo se si sta cercando di rilevare frequenze specifiche come ingresso DTMF. C'è una biblioteca C # DTMF generatore / rilevatore su Sourceforge sulla base di questo algoritmo.

Altri suggerimenti

Bellissima attuazione Goertzel è . C # modifica:

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;
    }

Funziona alla grande per me.

Ho trovato questo come una semplice implementazione di Goertzel. Non hanno ottenuto di lavorare ancora (alla ricerca di frequenza sbagliata?), ma ho pensato di condividerlo anywas. Si è copiato da questo sito .

        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)));
        }

diciamo Let quella tipica frequenza DTMF è 200Hz - 1000Hz. Allora dovreste rilevare un segnale in base a tra 4 e 20 cicli. FFT non ti porterà da nessuna parte credo, dato che verrà rilevare solo multipli di frequenze 50Hz: questa è una costruito in caratteristica di FFT, aumentando il numero di campioni sarà non risolvere il problema. Dovrete fare qualcosa di più intelligente.

Il tuo colpo migliore è quello di lineare dei minimi quadrati fit i dati per

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

per un dato omega (una delle frequenze DTMF). Vedere questo per i dettagli (in particolare come impostare un livello di significatività statistica) e dalle fermate dei letteratura.

Per quanto riguarda le librerie .NET che fanno questo tentativo TAPIEx ToneDecoder.Net Componente . Io lo uso per la rilevazione di DTMF, ma può fare toni personalizzati.

So che questa domanda è vecchio, ma forse farà risparmiare qualcun altro diversi giorni di ricerca e sperimentazione di esempi di codice e librerie che semplicemente non funzionano.

spettrale Analisi .

Tutte le applicazioni in cui si estraggono le frequenze dai segnali va in campo analisi spettrale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top