Return to LanScape's home page Go back a page...       Active TopicsActive Topics   Display List of Forum MembersMember List   Knowledge Base SearchSearch   HelpHelp  RegisterRegister  LoginLogin

LanScape VOIP Media Engine™ - Technical Support
 LanScape Support Forum -> LanScape VOIP Media Engine™ - Technical Support
Subject Topic: My DtmfDecoderCallbackProc is being called twice Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
ajdiaz
Junior
Junior


Joined: December 10 2007
Location: United States
Posts: 76
Posted: December 19 2007 at 2:07pm | IP Logged Quote ajdiaz

Any ideas why my DtmfDecoderCallbackProcedure() is being called twice.

I have a very simple app that displays in a message box the DTMF digit that is detected. The message box is displayed twice because the media engine is calling the callback procedure twice. I am only registering 1 line.

Lanscape Media Engine v5.12
Using .Net C#
Code:

Code:

static void SetDtmfDecoder()
{
    int PhoneLine =  0;
 
    DtmfDecoder = new VoipMediaEngine.DtmfDecoder();

    // create the decoder.
    status = DtmfDecoder.CreateDtmfDecoder(
                  MediaEngine,
                  true,               // use PCM samples.
                  8000,               // sample rate.
                  160,                // number of samples per input block.
                  160,                // filter block N size. generally set to the same as the num samples per block.
                  false,              // immediate mode.
                  DtmfDecoderCallbackProc, // handler proc.
                  MediaEngine              // handler proc instance data.
                  );

    if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
    {
        LogErrorMessage(MediaEngine, status, "CreateDtmfDecoder() Error.");
        DtmfDecoder.DestroyDtmfDecoder();
    }


    RxIvrChannel0 = new VoipMediaEngine.RxIvrChannel();
    int RxIvrSamplesPerIvrBuffer0 = 0;
    int RxIvrBytesPerIvrBuffer0 = 0;
    bool SamplesInByteArray0 = false;


    // tell the LanScape VOIP Media engine that we want to receive
    // streaming phone line audio data when the phone line is active.
    status = RxIvrChannel0.OpenRxIvrChannel(
                  MediaEngine,
                  PhoneLine,
                  IvrCallbackProc0,
                  MediaEngine,
                  true,          // Perform conversion.
                  // Receive Ivr Data Type.
                  VoipMediaEngine.AUDIO_BANDWIDTH.AUDIO_BW_PCM_8K,
                  ref RxIvrSamplesPerIvrBuffer0,
                  ref RxIvrBytesPerIvrBuffer0,
                  ref SamplesInByteArray0
                  );
    if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
    {
        LogErrorMessage(MediaEngine, status, "OpenRxIvrChannel() Error.");
    }
}

static void DtmfDecoderCallbackProc(VoipMediaEngine.DTMF_DETECT_DATA DtmfDetectData)
{
    VoipMediaEngine.DTMF_TONE DtmfTone = (VoipMediaEngine.DTMF_TONE)DtmfDetectData.DtmfTone;

    MessageBox.Show("You entered " + DtmfTone.ToString());

}



Back to Top View ajdiaz's Profile Search for other posts by ajdiaz
 
ajdiaz
Junior
Junior


Joined: December 10 2007
Location: United States
Posts: 76
Posted: December 19 2007 at 2:18pm | IP Logged Quote ajdiaz

Please ignore code above. It is incomplete.

Code:

Code:

//User clicks on button to handle dtmf example
private void buttonWaitCallHandleDTMF_Click(object sender, EventArgs e)
{
      //star t the engine
      MyMediaEngine MediaEngine = InitializeMyMediaEngineByAlex();

      VoipMediaEngine.TELEPHONY_RETURN_VALUE  status;

      // The phone line we want to use
      int PhoneLine = 0;

      status = MediaEngine.DisableSipRegisterServer();

      status = MediaEngine.EnableSipDomain(DomainName);

      status = MediaEngine.EnableSipProxyServer(SipProxy, SipProxyPort);

      status = MediaEngine.SetCallTerminateTimeout(2000);

      // start SIP registration functions.
      status = MediaEngine.EnableSipRegisterServer(
          PhoneDisplayName,
          false,
          false,
          SipProxy,
          SipProxyPort,
          36000,
          36000,
          2000,
          false
          );

      status = MediaEngine.TriggerRegistration();
      status = MediaEngine.RegistationErrorRetryTime(2000);
      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "EnableSipRegisterServer() Error.");
      }


      // Frequency ratio table for inclusion into source code.
      // Used to tune the DTMF detector.
      //
      VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT [] DtmfDecoderRatioTuningTable = new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT[16]
      {
          //     Low Freq Ratio,High Freq Ratio
          //     ------------------------------------------------------
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(62,709),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(15,1033),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(17,1201),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(117,869),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(118,786),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(67,838),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(9,549),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(12,935),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(219,617),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(182,705),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(135,1015),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(15,820),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(783,2376),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(306,794),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(222,757),
          new VoipMediaEngine.FREQUENCY_RATIO_TABLE_ELEMENT(123,861)
      };

       // Frequency magnitude table for inclusion into source code.
       // Used to tune the DTMF detector.
       //
       VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ ELEMENT[] DtmfDecoderMagnitudeTuningTable = new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT[16]
       {
            //     MinMagF1,MaxMagF1,MinMagF2,MaxMagF2,MinMag2ndHarmF1,MaxMag2ndHarmF1,MinMag2ndHarmF2,MaxMag2ndHarmF2
            //     -----------------------------------------------------------------------------------------------------
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(107608188, 496445004,103411194,443717266,411197,2195591,1522,178031),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(98703977,5 11868275,80885942,390186326,3874642,19991392,300,138363),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(99486517,4 92838380,61407098,230404150,4516086,21626116,390,184719),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(101966309, 486157921,78254689,330155114,184132,2186855,1868,154810),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(72738722,2 91167037,88328883,454033006,2937,1401190,569,325576),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(67983788,3 11361964,82167593,426290134,267340,3775872,2,378513),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(74958663,2 96326136,71113935,248650135,4598403,29679080,801,452758),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(68035984,2 91050178,74458607,340819931,3457677,16775569,284,357010),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(99100032,4 92246061,89302963,434986397,24948,657561,1210,204680),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(105367119, 489576272,86913068,394091723,68566,848058,1767,197661),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(101971486, 489633999,60985442,228926806,273346,2854382,307,156896),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(98562873,4 90116500,77690299,321257598,4215483,21956753,1457,134067),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(93170491,4 59011273,93448825,459611558,2526,147707,354,50236),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(97704284,4 82497568,90082863,399339125,15371,716030,828,241350),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(93728174,4 53863426,62869872,235221759,56773,1405407,16,286438),
            new  VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(91761953,4 43736883,79158506,334015678,201584,2309188,467,230855)
       };

      DtmfDecoder = new VoipMediaEngine.DtmfDecoder();

      MyCALLBACK_DATAClass mycb = new MyCALLBACK_DATAClass();
      mycb.MediaEngine = MediaEngine;
      mycb.PhoneLine = 0;
      
      // create the decoder.
      status = DtmfDecoder.CreateDtmfDecoder(
                    MediaEngine,
                    true,                                  // use PCM samples.
                    8000,                                  // sample rate.
                    160,                                  // number of samples per input block.
                    160,                                  // filter block N size. generally set to the same as the num samples per block.
                    false,                                  // immediate mode.
                    DtmfDecoderCallbackProc,     // handler proc.
                    mycb                                 // handler proc instance data.
                    );

      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "CreateDtmfDecoder() Error.");
          DtmfDecoder.DestroyDtmfDecoder();
      }


      RxIvrChannel0 = new VoipMediaEngine.RxIvrChannel();
      int RxIvrSamplesPerIvrBuffer0 = 0;
      int RxIvrBytesPerIvrBuffer0 = 0;
      bool SamplesInByteArray0 = false;

      mycb.DtmfDecoder = DtmfDecoder;

      // tell the LanScape VOIP Media engine that we want to receive
      // streaming phone line audio data when the phone line is active.
      status = RxIvrChannel0.OpenRxIvrChannel(
                    MediaEngine,
                    PhoneLine,
                    IvrCallbackProc0,
                    mycb,        //MediaEngine,
                    true,                                                                    // Perform conversion.
                    // Receive Ivr Data Type.
                    VoipMediaEngine.AUDIO_BANDWIDTH.AUDIO_BW_PCM_8K,
                    ref RxIvrSamplesPerIvrBuffer0,
                    ref RxIvrBytesPerIvrBuffer0,
                    ref SamplesInByteArray0
                    );
      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "OpenRxIvrChannel() Error.");
      }

      //Read y to answer a call
      WaitForOkToAnswerCall(MediaEngine,  PhoneLine);

      VoipMediaEngine.LINE_STATE  LineState = new VoipMediaEngine.LINE_STATE();

      status = MediaEngine.GetLineStatus(PhoneLine, LineState);
      String CurStateStr = MediaEngine.GetTelephonyStatusString(LineState.State);

      status = MediaEngine.GoOffHook(PhoneLine);
      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "GoOffHook() Error.");
      }

      WaitForInCall(MediaEngine,  PhoneLine);

      status = MediaEngine.GetLineStatus(PhoneLine, LineState);
      CurStateStr = MediaEngine.GetTelephonyStatusString(LineState.State);

      VoipMediaEngine.SIP_INCOMING_CALL_INFO  IncomingCallInfo = new VoipMediaEngine.SIP_INCOMING_CALL_INFO();
      status = MediaEngine.GetIncomingCallInfo(PhoneLine, IncomingCallInfo);
      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "GetIncomingCallInfo() Error.");
      }

      VoipMediaEngine.SIP_ACTIVE_CALL_INFO  ActiveCallInfo = new VoipMediaEngine.SIP_ACTIVE_CALL_INFO();
      status = MediaEngine.GetActiveCallInfo(PhoneLine, ActiveCallInfo);
      if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
      {
          LogErrorMessage(MediaEngine, status, "GetActiveCallInfo() Error.");
      }
}


static void DtmfDecoderCallbackProc(VoipMediaEngine.DTMF_DETECT_DATA DtmfDetectData)
{

      VoipMediaEngine.DTMF_TONE  DtmfTone = (VoipMediaEngine.DTMF_TONE)DtmfDetectData.DtmfTone;

      MessageBox.Show("You  entered " + DtmfTone.ToString());

}


static void IvrCallbackProc0(VoipMediaEngine.IVR_RECOGNITION_DATA IvrRecognitionData)
{

      MyMediaEngine MediaEngine;
      MyCALLBACK_DATAClass  mycb;
      bool status;

      //// access the user defined parameter.
      mycb = (MyCALLBACK_DATAClass)IvrRecognitionData.UserData;
      MediaEngine = mycb.MediaEngine;
      VoipMediaEngine.DtmfDecoder  pDtmfDecoder = mycb.DtmfDecoder;


      status =  pDtmfDecoder.DtmfDecoderWrite(IvrRecognitionData.SampleBuffe r);
}


     

Back to Top View ajdiaz's Profile Search for other posts by ajdiaz
 
juice
Vetran
Vetran


Joined: December 05 2006
Location: United States
Posts: 139
Posted: December 19 2007 at 2:39pm | IP Logged Quote juice

Sorry, I didn't much read your code.

Couple suggestions:
* You get a callback for pressed and released. Maybe that is why you see it twice?

* Non PCMU or lots of packet loss, or other Rtp issues can result in bad detection of dtmf from what I've seen.
Back to Top View juice's Profile Search for other posts by juice
 
ajdiaz
Junior
Junior


Joined: December 10 2007
Location: United States
Posts: 76
Posted: December 19 2007 at 2:55pm | IP Logged Quote ajdiaz

That was it! You get a callback for key pressed and another for key released.

Thanks.

-Alex
Back to Top View ajdiaz's Profile Search for other posts by ajdiaz
 
support
Administrator
Administrator


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: December 20 2007 at 10:17am | IP Logged Quote support

Hi aj,

One other item, you do not have to bother with specifying your own DtmfDecoderRatioTuningTable or DtmfDecoderMagnitudeTuningTable objects unless you want to re-tune the in-band DTMF decoder. The DTMF decoder is already tuned to specs.

Also, thanks juice for your post.

We are having a bit of a POP3 email server issue here so we are not currently getting automated post updates via email. Hopefully this gets fixed shortly. We will manually continue to monitor this forum throughout today.


Support
Back to Top View support's Profile Search for other posts by support Visit support's Homepage
 

If you wish to post a reply to this topic you must first login
If you are not already registered you must first register

  Post ReplyPost New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum






Contact LanScape Hear what the Lawyers have to say How youm may use this site Read your privacy rights