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: Having a really tough problem with DTMF Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
ajay__soni
Intermediate
Intermediate


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: August 29 2008 at 7:39pm | IP Logged Quote ajay__soni

Hi,

I hope you can really help me with DTMF issue.

I am doing a basic recognition of DTMF on an outbound call in C#. I can make the call no problem.

When I use the DTMF recogniser it doesn't work. So I recorded the outbound call to a file using the API StartPhoneLineRecording().

The voice is fine "testing 123 ", but when I type DTMF on my phone I get distorted buzzes. I have uploaded the file here:

http://ftp.enjector.com/temp/DTMFTest1.wav

I initialise using the following:

StartParams.AudioRecordBandWidth = VoipMediaEngine.AUDIO_BANDWIDTH.AUDIO_BW_ALAW_8K;

StartParams.AudioPlaybackBandWidth = VoipMediaEngine.AUDIO_BANDWIDTH.AUDIO_BW_ALAW_8K;

I turned of DTMF recognition and just recorded directly to file.

Nothing complicated.

Please help, I can continue with my project this weekend.

Many thanks

Ajay

Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
ajay__soni
Intermediate
Intermediate


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: August 29 2008 at 7:51pm | IP Logged Quote ajay__soni

Hi,

Just did another test on another machine but using the SingleLine Phone.exe (C++). I got the same issue:

I have uploaded the recording here:

http://ftp.enjector.com/temp/SingLinePhoneTest1.wav

All tests were done with alaw and ulaw. Same issue.

I'm connecting via asterisk to an outside PSTN trunk. The box accepts alaw and ulaw enabled.

Thanks

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
ajay__soni
Intermediate
Intermediate


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: August 29 2008 at 8:00pm | IP Logged Quote ajay__soni

Hi,

Sorry for posting again. I just did a test with xlite directly to the same asterisk box and I can hear the DTMFs perfectly.

Thanks

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
ajay__soni
Intermediate
Intermediate


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: August 30 2008 at 2:19am | IP Logged Quote ajay__soni

Hi,

I looked through the forum board and got something working well using RTP analysis in C#. I would like to share this to anyone having the same problem.

NOTE: You must set dtmfmode=rfc2833 in your asterisk sip.conf to get this to work.


static void RtpPacketAccessCallbackProc(VoipMediaEngine.RAW_RTP_DATA RawRtpData)
        {
            MyMediaEngine MediaEngine;

            // Access the user defined parameter.
            MediaEngine = (MyMediaEngine)RawRtpData.UserData;

            // Can't access RTP hearder to see if audio - let's assume audio anyway
            //if((RawRtpData.RtpPacketBuffer pRtpHeader.PayloadType == 101)
            //{

            //}

            if (RawRtpData.TransmittingPacket == false)
            {

               // Access the DTMF payload as a 32 bit value                    
               uint NumDtmfPayloads = (RawRtpData.RtpPacketLengthInBytes - RawRtpData.RtpHeaderLengthInBytes) / 4;
               if (NumDtmfPayloads == 1)
               {
                    byte[] array = RawRtpData.RtpPacketBuffer;
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(array);
                    }

                    uint DtmfPayload = BitConverter.ToUInt32(array, 0);

                    // Parse the DTMF payload values.
                    // the DTMF key pressed or released.
                    uint DTMF_Event = DtmfPayload >> 24;

                    // the "end" bit.
                    uint DTMF_E = (DtmfPayload >> 23) & 0x01;

                    // reserved bit - not used.
                    uint DTMF_R = (DtmfPayload >> 22) & 0x01;

                    // the DTMF power level (volume).
                    uint DTMF_Volume = (DtmfPayload >> 16) & 0x3f;

                    // tone duration.
                    uint DTMF_Duration = DtmfPayload & 0xffff;

                    Console.WriteLine(DTMF_Event + " " + DTMF_E + " " + DTMF_R + " " + DTMF_Volume + " " + DTMF_Duration);

                    RawRtpData.ProcessRtpPacket = false;

                    // tell the media enigne to ignore this RTP DTMF packet.
                    // if you don't do this, the RTP receiver logic will try
                    // to interpret the DTMF payload as encoded audio.
                    RawRtpData.ProcessRtpPacket = false;
               }
            }
        }

        static VoipMediaEngine.RtpPacketAccess RtpPacketAccess;

        public static void EnableRTP(int PhoneLine)
        {
            VoipMediaEngine.TELEPHONY_RETURN_VALUE status;

            RtpPacketAccess = new VoipMediaEngine.RtpPacketAccess();

            status = RtpPacketAccess.EnableRawRtpPacketAccess(
                        MediaEngine,
                        PhoneLine,
                        true,
                        RtpPacketAccessCallbackProc,
                        MediaEngine
                        );
        }

Have fun!

Ajay Soni
Enjector Software Ltd.
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
support
Administrator
Administrator


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: September 02 2008 at 9:07am | IP Logged Quote support

Hi Ajay,

Good job. At least you came to some solution by the power of your own investigation. Thanks also for taking the time to post your solution and your findings. That really helps everyone down the road.

Just to be sure:

1)
You are now using the RFC2833 integrated DTMF capability in the media engine right?

Note: The media engine can handle RFC2833 DTMF detection and generation automatically for your C# app. You can still use the “RtpPacketAccessCallbackProc” method as you posted but that technique is duplicating the functionality already built into the media engine. We are assuming you used the “RtpPacketAccessCallbackProc” method just to perform DTMF debugging and trouble shooting– which is good.

2)
If you use the fully integrated RFC2833 dtmf detection/generation of the media engine in your C# app, you will have “rock solid” DTMF capability between your C# .NET VOIP app and Asterisk.


Support

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


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: September 02 2008 at 9:08am | IP Logged Quote support

Ajay,

By the way, don’t worry about posting too much. Its all good…..

Support


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


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: September 02 2008 at 9:55am | IP Logged Quote ajay__soni

Hi,

Thanks for your post. Where/how can I access this DTMF information from the media engine?

I can't seem to find a way of doing this.

My engine version is 5.12.8.1

Thanks

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
support
Administrator
Administrator


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: September 02 2008 at 10:35am | IP Logged Quote support

Ajay,

Your support FTP account contains an engineering release (v5.12.8.7) of the media engine that contains the fully integrated DTMF capability. This version contains capabilities that will be released in the v6 media engine product that will be made available shortly. You will automatically be receiving a new product image as soon as v6 is made available. Please see the “Engineering Update v5.12.8.7” directory.

Simply take the following files from the engineering release and manually update your installed product image:

LanScape_Software_Developer's_Reference.chm (optional)
LMEVoip.dll
LMEVoip.lib
LMEVoipManaged.dll
SipTelephonyApi.h

Then make sure to rebuild your VOIP app.

If using the engineering release, make sure to use the updated C# license file from the “Engineering Update v5.12.8.7\License Files” directory of your support FTP account.

This engineering release is good until the end of this year (12-31-08), then it will no longer function.

See the updated Software Developer’s Reference for the “DTMF Generation and Detection” section. It will give you all the APIs that are now available to have the media engine perform fully integrated in-band and RFC2833 DTMF generation and detection for your app. Post your questions to a new forum thread if you run into problems.

The nice thing about this new DTMF capability is that when the media engine detects in-band and/or RFC2833 DTMF being received on a phone line, it sends your app a DTMF ON/OFF event. All your app needs to do is enable the proper type of DTMF on a per phone line basis and then process DTMF detection events when they are sent to your app. Nice and simple.

Let us know if we have forgotten something.


Support


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


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: September 02 2008 at 11:51am | IP Logged Quote ajay__soni

Hi,

Thanks for that. Great addition but not working:

When I look at the DTMF digits (VoipMediaEngine.DTMF_DETECT_DATA.DtmfTone) I always get:

DTMF Detected: 6
DTMF Detected: 1
DTMF Detected: 1
DTMF Detected: 6
DTMF Detected: 6
DTMF Detected: 1
DTMF Detected: 1
DTMF Detected: 6
DTMF Detected: 6
DTMF Detected: 1
DTMF Detected: 1

This output comes from this code I put together from your samples:

(Sorry for the size)

Code:

static VoipMediaEngine.DtmfDecoder DtmfDecoder;

public static void DTMFEnableDetection()
{
    VoipMediaEngine.TELEPHONY_RETURN_VALUE status;

    // 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,511868275,80885942,390186326,3874642,19991392,300,138363),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(99486517,492838380,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,291167037,88328883,454033006,2937,1401190,569,325576),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(67983788,311361964,82167593,426290134,267340,3775872,2,378513),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(74958663,296326136,71113935,248650135,4598403,29679080,801,452758),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(68035984,291050178,74458607,340819931,3457677,16775569,284,357010),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(99100032,492246061,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,490116500,77690299,321257598,4215483,21956753,1457,134067),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(93170491,459011273,93448825,459611558,2526,147707,354,50236),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(97704284,482497568,90082863,399339125,15371,716030,828,241350),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(93728174,453863426,62869872,235221759,56773,1405407,16,286438),
                new VoipMediaEngine.FREQUENCY_MAGNITUDE_TABLE_ELEMENT(91761953,443736883,79158506,334015678,201584,2309188,467,230855)
        };

    DtmfDecoder = new VoipMediaEngine.DtmfDecoder();

    // create the decoder.
    status = DtmfDecoder.CreateDtmfDecoder(
                MediaEngine,
                false,                              // I'm using ULAW
                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.
                );
}

static void PhoneLineReceiveAudioCallback(VoipMediaEngine.IVR_RECOGNITION_DATA pIvrRecognitionData)
{
    bool result = DtmfDecoder.DtmfDecoderWrite(pIvrRecognitionData.SampleBuffer);
    if (result == false)
    {
        Console.Write("x");
    }
}

public static void ListenForDTMF(int PhoneLine)
{
    DTMFEnableDetection();

    VoipMediaEngine.TELEPHONY_RETURN_VALUE status;

    VoipMediaEngine.RxIvrChannel RxIvrChannel = new VoipMediaEngine.RxIvrChannel();
    int ChannelNumber = 0;
    int BytesPerIvrBuffer = 0;
    bool SamplesInByteArray = false;

    status = RxIvrChannel.OpenRxIvrChannel(
                MediaEngine,
                PhoneLine,
                PhoneLineReceiveAudioCallback,
                MediaEngine,
                true,
                VoipMediaEngine.AUDIO_BANDWIDTH.AUDIO_BW_ULAW_8K,
                ref ChannelNumber,
                ref BytesPerIvrBuffer,
                ref SamplesInByteArray);

    if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
    {
        string CurStateStr = MediaEngine.GetTelephonyStatusString(status);
        Console.WriteLine("error listening to DTMF " + CurStateStr);
    }
}

static void DtmfDecoderCallbackProc(VoipMediaEngine.DTMF_DETECT_DATA DtmfDetectData)
{
    string digitPressed = null;

    switch (DtmfDetectData.DtmfTone)
    {
        case VoipMediaEngine.DTMF_TONE.DtmfTone0:
            digitPressed = "0";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone1:
            digitPressed = "1";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone2:
            digitPressed = "2";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone3:
            digitPressed = "3";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone4:
            digitPressed = "4";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone5:
            digitPressed = "5";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone6:
            digitPressed = "6";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone7:
            digitPressed = "7";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTone8:
            digitPressed = "8";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfToneAsterisk:
            digitPressed = "*";
            break;
        case VoipMediaEngine.DTMF_TONE.DtmfTonePound:
            digitPressed = "#";
            break;
        default:
            digitPressed = "?";
            break;
    }

    Console.WriteLine("DTMF Detected: " + digitPressed);
}


Any ideas?

Thanks

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
ajay__soni
Intermediate
Intermediate


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: September 02 2008 at 12:13pm | IP Logged Quote ajay__soni

Hi,

Oh sweet. I realised I'm still doing inband analysis! I stripped the code and used your new RFC2833 API.

For anyone else having problems do this.

1) Do this on startup:
StartParams.DtmfEnabled = true;

2) Create a new event handler in your main SIP handler:

Code:

case VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipDtmfDigitEvent:
    VoipMediaEngine.DTMF_EVENT_DATA ev = (VoipMediaEngine.DTMF_EVENT_DATA) EventData;
    Console.WriteLine("Got digit: " + ev.PhoneLine + " " + ev.DtmfTone + " " + ev.StateOn);
    break;


3) Simply enable DTMF detection by doing the following:

Code:

VoipMediaEngine.TELEPHONY_RETURN_VALUE status;
status = MediaEngine.InitializeRfc2833DtmfDecoder(PhoneLine);
if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
{
    Console.WriteLine("Error listening to DTMF " + status.ToString());
    return;
}

status = MediaEngine.SetRfc2833DtmfDecoderEnableState(PhoneLine, true);
if (status != VoipMediaEngine.TELEPHONY_RETURN_VALUE.SipSuccess)
{
    Console.WriteLine("Error listening to DTMF " + status.ToString());
    return;
}


Thanks Support.

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
support
Administrator
Administrator


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: September 02 2008 at 12:25pm | IP Logged Quote support

Ajay,

Your last post is right on. Good job. You should now have rock solid RFC2833 DTMF detection from your Asterisk (PSTN gateway) box to your IVR server app.

Support

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


Joined: December 01 2007
Location: United Kingdom
Posts: 19
Posted: December 17 2008 at 4:35am | IP Logged Quote ajay__soni

Hi,

The engineering release you gave me with the DTMF fix is about to expire on v5.12.8.7.

Can i have an updated version that won't expire?

Thanks

Ajay
Back to Top View ajay__soni's Profile Search for other posts by ajay__soni
 
support
Administrator
Administrator


Joined: January 26 2005
Location: United States
Posts: 1666
Posted: December 17 2008 at 9:21am | IP Logged Quote support

Hi Ajay,

I’m glad you posted. Yes we have on record that you need an update. I will send you an email with additional information.

Thanks,


Randal


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