Advertisement
Guest User

DTMF Detection with Goertzel

a guest
Dec 10th, 2015
1,047
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.64 KB | None | 0 0
  1. using NAudio.Wave;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5.  
  6. namespace DtmfDetector
  7. {
  8.     class Program
  9.     {
  10.         private const int SampleBlockSize = 205;
  11.  
  12.         private static readonly double[] frequencies = new[] { 697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0 };
  13.  
  14.         private static readonly Dictionary<int, Dictionary<int, string>> phoneKeyOf = new Dictionary<int, Dictionary<int, string>>
  15.         {
  16.             {1209, new Dictionary<int, string> {{1477, "?"}, {1336, "?"}, {1209, "?"}, {941, "*"}, {852, "7"}, {770, "4"}, {697, "1"}}},
  17.             {1336, new Dictionary<int, string> {{1477, "?"}, {1336, "?"}, {1209, "?"}, {941, "0"}, {852, "8"}, {770, "5"}, {697, "2"}}},
  18.             {1477, new Dictionary<int, string> {{1477, "?"}, {1336, "?"}, {1209, "?"}, {941, "#"}, {852, "9"}, {770, "6"}, {697, "3"}}},
  19.             { 941, new Dictionary<int, string> {{1477, "#"}, {1336, "0"}, {1209, "*"}, {941, "?"}, {852, "?"}, {770, "?"}, {697, "?"}}},
  20.             { 852, new Dictionary<int, string> {{1477, "9"}, {1336, "8"}, {1209, "7"}, {941, "?"}, {852, "?"}, {770, "?"}, {697, "?"}}},
  21.             { 770, new Dictionary<int, string> {{1477, "6"}, {1336, "5"}, {1209, "4"}, {941, "?"}, {852, "?"}, {770, "?"}, {697, "?"}}},
  22.             { 697, new Dictionary<int, string> {{1477, "3"}, {1336, "2"}, {1209, "1"}, {941, "?"}, {852, "?"}, {770, "?"}, {697, "?"}}}
  23.         };
  24.  
  25.         public static void Main(string[] args)
  26.         {
  27.             using (WaveFileReader waveFile = new WaveFileReader("dtmftest.wav"))
  28.             {
  29.                 var sampleRate = waveFile.WaveFormat.SampleRate;
  30.                 var samples = waveFile.ToSampleProvider();
  31.  
  32.                 var sampleBlock = new float[SampleBlockSize];
  33.  
  34.                 while (samples.Read(sampleBlock, 0, SampleBlockSize) == SampleBlockSize)
  35.                 {
  36.                     var magnitudes = frequencies.Select(frequency => new
  37.                     {
  38.                         Frequency = frequency,
  39.                         Magnitude = CalculateGoertzel(sampleBlock, frequency, sampleRate)
  40.                     }).ToList();
  41.  
  42.                     var sortedMagnitudes = magnitudes.OrderByDescending(result => result.Magnitude);
  43.                     var highestMagnitudes = sortedMagnitudes.Take(2).ToList();
  44.  
  45.                     if (highestMagnitudes.All(result => result.Magnitude > 10.0))
  46.                     {
  47.                         var key = phoneKeyOf[(int)highestMagnitudes[0].Frequency][(int)highestMagnitudes[1].Frequency];
  48.  
  49.                         Console.WriteLine(
  50.                             waveFile.CurrentTime.TotalSeconds.ToString("00.000") + "s: [" + key + "] key; "
  51.                             + "mags = { " + magnitudes.Select(result => result.Magnitude.ToString("00.000")).Aggregate((result1, result2) => result1 + " ; " + result2) + " }");
  52.                     }
  53.                 }
  54.             }
  55.         }
  56.  
  57.         private static double CalculateGoertzel(float[] samples, double frequency, int sampleRate)
  58.         {
  59.             var normalizedFrequency = Math.Round(frequency * samples.Length / sampleRate);
  60.             var w = (2.0 * Math.PI / samples.Length) * normalizedFrequency;
  61.             var cosine = Math.Cos(w);
  62.             var sine = Math.Sin(w);
  63.             var coeff = 2.0 * cosine;
  64.  
  65.             var q0 = 0.0;
  66.             var q1 = 0.0;
  67.             var q2 = 0.0;
  68.  
  69.             foreach(var sample in samples)
  70.             {
  71.                 q0 = coeff * q1 - q2 + sample;
  72.                 q2 = q1;
  73.                 q1 = q0;
  74.             }
  75.  
  76.             return Math.Sqrt(q1 * q1 + q2 * q2 - q1 * q2 * coeff);
  77.         }
  78.     }
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement