How to use the DTMFRecognitionEngine class in Microsoft.Speech
Asked Answered
J

1

7

The Microsoft.Speech SDK has a DTMFRecognitionEngine class, which I'd like to experiment with - we need to detect DTMF tones within a WAV file (I realise there are other ways to do this, but I'm evaluating all possible methods).

The documentation isn't clear on how to actually use the class: it's companion class, SpeechRecognitionEngine, has plenty of examples and nice clear methods like SetInputToWaveFile. DTMFRecognitionEngine doesn't have any such methods.

Could someone provide insight on how I can use this component in my own code?

EDIT: It appears that there isn't any way to use this class for ... well, anything much really. I'm looking for a library that will allow me to detect the position and duration of DTMF digits in an audio file. I've looked at TapiEx, but they're not responding to emails. If anyone has any other suggestions, they'd be gratefully received...

Jere answered 22/11, 2015 at 18:43 Comment(3)
... and, straight away, a close vote for being "too broad". Not sure how I can make the question any "narrower", given the actual documentation itself doesn't give much of a clue? It seems I'm not the only one: codeproject.com/Questions/423912/How-to-detect-a-DTMF-soundJere
I think the difficult part is just asking directly for a source example. Maybe there's a way to rephrase this question where you can kind of make it a little less like, "Someone please give me code" and something more like, "Could someone provide insight on how this part works?"Aphotic
Unfortunately this kind of community review system can kind of preserve close votes from those who may not look twice at the thread. If it gets closed, with this edit in place, I think it should pass and you should be able to reopen it. Also while you work at this, the more details you edit and add, the better. It might be hard to find help on this question with this kind of exotic API/documentation -- but good luck!Aphotic
C
2

It would appear that this is not possible. I even went so far as to get the private _engine of DtmfRecognitionEngine which is a wrapper the SpeechRecognitionEngine and call its SetInputToWaveFile with no luck. Apparently the only way to get a tone into the DtmfRecognitionEngine is to call AddTone(). I've included a sample grammar file and some source code that you can play with. Interestingly, if you uncomment the dre.AddTone()'s you see both sre's events and dre's events are getting fired.

Switching the call to sre.RecognizeAsync() does not help.

Looks like you'll need a different library...

PinGrammar.xml

<?xml version="1.0"?>
<grammar mode="dtmf" version="1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.w3.org/2001/06/grammar 
                             http://www.w3.org/TR/speech-grammar/grammar.xsd"
         xmlns="http://www.w3.org/2001/06/grammar"
         root="pin">

  <rule id="digit">
    <one-of>
      <item> 0 </item>
      <item> 1 </item>
      <item> 2 </item>
      <item> 3 </item>
      <item> 4 </item>
      <item> 5 </item>
      <item> 6 </item>
      <item> 7 </item>
      <item> 8 </item>
      <item> 9 </item>
    </one-of>
  </rule>

  <rule id="pin" scope="public">
    <one-of>
      <item>
        <item repeat="4">
          <ruleref uri="#digit"/>
        </item>
        #
      </item>
      <item>
        * 9
      </item>
    </one-of>
  </rule>

</grammar>

Source:

using Microsoft.Speech.Recognition;
using System.Reflection;

namespace DTMF_Recognition
{
    class Program
    {
        static void Main(string[] args)
        {
            Grammar grammar = null;
            grammar = new Grammar("PinGrammar.xml");

            DtmfRecognitionEngine dre = new DtmfRecognitionEngine();
            dre.DtmfRecognized += dre_DtmfRecognized;

            FieldInfo field = typeof(DtmfRecognitionEngine).GetField("_engine", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
            var wrapper = field.GetValue(dre);
            FieldInfo engineField = wrapper.GetType().GetField("_engine", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
            SpeechRecognitionEngine sre = (SpeechRecognitionEngine)engineField.GetValue(wrapper);

            dre.DtmfHypothesized += dre_DtmfHypothesized;
            dre.DtmfRecognitionRejected += dre_DtmfRecognitionRejected;
            dre.RecognizeCompleted += dre_RecognizeCompleted;
            dre.LoadGrammar(grammar);

            //dre.AddTone(DtmfTone.One);
            //dre.AddTone(DtmfTone.Two);
            //dre.AddTone(DtmfTone.Three);
            //dre.AddTone(DtmfTone.Four);
            //dre.AddTone(DtmfTone.Hash);

            sre.SetInputToWaveFile(@"C:\Users\Clay Ver Valen\Desktop\3.wav");
            sre.SpeechHypothesized += sre_SpeechHypothesized;
            sre.SpeechDetected += sre_SpeechDetected;
            sre.SpeechRecognitionRejected += sre_SpeechRecognitionRejected;

            dre.RecognizeAsync();
            System.Threading.Thread.Sleep(30000);
        }

        static void sre_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            int i = 1;
        }

        static void sre_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            int i = 1;
        }

        static void sre_SpeechDetected(object sender, SpeechDetectedEventArgs e)
        {
            int i = 1;
        }

        static void dre_DtmfRecognitionRejected(object sender, DtmfRecognitionRejectedEventArgs e)
        {
            int i = 1;
        }

        static void dre_DtmfHypothesized(object sender, DtmfHypothesizedEventArgs e)
        {
            int i = 1;
        }

        static void dre_RecognizeCompleted(object sender, DtmfRecognizeCompletedEventArgs e)
        {
            int i = 1;
        }

        static void dre_DtmfRecognized(object sender, DtmfRecognizedEventArgs e)
        {
            int i = 1;
        }
    }
}
Cenozoic answered 1/12, 2015 at 1:55 Comment(2)
You'll need your own WAV file with DTMF tones, I figured you already had that though...Cenozoic
I was afraid that would be the case. I've looked at the component from TapiEx, but they're not responding to emails which worries me... I'll update the original question: can anyone suggest a library which can detect DTMF tones (with a view to removing them, so I need exact positions and durations of the tone)?Jere

© 2022 - 2024 — McMap. All rights reserved.