Sending DTMF Tones with Asterisk

I have a need to send DTMF tones through a specific channel while in a call.

My function is working as expected, the only problem is the AJAM Action command 'PlayDTMF' will only send 1 digit at a time.  I need to send a single digit, pause, and then send a 10 digit phone number.

The single digit plays as expected, and I created a for next loop in my javascript app that will play each individual digit from the phone number.  The loop processes so fast that only the 1st one or two digits actually gets played.  Alll other digits result in the rather nebulous error "No Such Channel".

I've tried pausing the script by using a 'sleep' function, but only 5-6 digits actually get sent out, all digits are 'Successfully Queued', but not all are sent.  I've also tried 'setTimeout' and then reference a function to be called.  This method fails as it doesn't return to my for loop, it just simply ends processing once the function has been called.

some function() {
for (x=0;x<=9;x++) {
singleDigit = cidDTMF.substr(x,1);
astmanEngine.sendRequest('action=PlayDTMF&Channel=' + viciChannel + '&Digit=' + singleDigit);
setTimeout(sendTones(singleDigit),1000);
            }
}

function sendTones(dtmfDigit) {
astmanEngine.sendRequest('action=PlayDTMF&Channel=' + viciChannel + '&Digit=' + dtmfDigit);
}
            
Any suggestion would be greatly appreciated.
jcorbitAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Michel PlungjanIT ExpertCommented:
You need to split the function so it is not a tight loop


var nofTones = 9;
var x = 0;
function loopTones() {
  if (x>=nofTones) return;// stop
  var singleDigit  = cidDTMF.charAt(x);
  astmanEngine.sendRequest('action=PlayDTMF&Channel='  + viciChannel + '&Digit=' + singleDigit);
  setTimeout('loopTones()',500);
  x++
}

0
jcorbitAuthor Commented:
Thanks for the suggestion, I incorporated the changes into my script, and initially it looks good.  Unfortunately, I'm still seeing the issue of not all the digits going through.

I also created a 'Numeric Pad' for the Agents to manually send the necessary tones - This function fails much the same as before.  Some digits will be sent, while others are not.

In all cases,(loop or keypad) I receive a message "DTMF successfully queued', whether the tones plays out to the receiving channel or not.

I'm now wondering if it's an issue with AJAM/Asterisk - are there any other methods of sending out DTMF?  I've looked but can't find anything other than PlayDTMF (AJAM) or SendDTMF (AGI) - I cannot seem to incorporate the SendDTMF into my Javascript/PHP app.
0
Michel PlungjanIT ExpertCommented:
http://www.dsptutor.freeuk.com/dtmf/ToneGenerator.html

haha: Note that the applet works much more effectively if you have a sound       card. If you don't, you just have to hum the tones yourself.
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

jcorbitAuthor Commented:
That's an interesting App, but would it send the tones out through an Asterisk channel?  All of my Agents are running on Linux Thin-Clients without the sound cards being active (sound is dedicated to the Twinkle Soft-Phone).
0
Michel PlungjanIT ExpertCommented:
Sorry, I did not realise that asterix is an application

Likely not

We need to look at the Asterix API to see why it does not work


0
Michel PlungjanIT ExpertCommented:
http://www.voip-info.org/wiki/view/Asterisk+DTMF

Modify DTMF timing Q: How and where can I adjust the DTMF timing?
A: main/channel.c, include/asterisk/channel.h:  2007-04-24 21:34 +0000 [r61781-61787]  Russell Bryant (Asterisk  1.4.3)
Improve DTMF handling in ast_read() even more in response to a  discussion on the asterisk-dev mailing list. I changed the enforced  minimum length of a digit from 100ms to 80ms. Furthermore, I made it now  enforce a gap of 45ms in betw
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jcorbitAuthor Commented:
Thanks for the DTMF link - hard to believe I haven't see that in all my searches over the past couple of days.

Will try and tweak my Asterisk setup to see if that will help.
0
jcorbitAuthor Commented:
Success.  After reading the link you so graciously provided, I changed dtmfmode=auto to dtmfmode=info.  Now the tones are generated and sent every time.  The java function was extremely helpful, I could not figure out the setTImeout function.

Thanks for all your help!
0
Michel PlungjanIT ExpertCommented:
Great :)

The function I posted was to be called thusly:



var nofTones = 9; // assuming this is standard
var x = 0; // needs to be set each time
var cidDTMF = "";
function loopTones() {
   if (x>=nofTones) return;// stop
  var singleDigit  =  cidDTMF.charAt(x);
  astmanEngine.sendRequest('action=PlayDTMF&Channel='   + viciChannel + '&Digit=' + singleDigit);
   setTimeout('loopTones()',500);
  x++
}

function callIt(num) {
  cidDTMF = String(num);
  x = 0;
  loopTones();
}

callIt(123456789)
0
jcorbitAuthor Commented:
This is how I incorporated your example (includes AJAM login).  Function is called from a button on the user screen after initiating a Warm Transfer.  Will send 1 Digit to the answering IVR as answer to First Question, and then the 10 digit phone number in answer to the second question.


numTones = 10;
dCount = 0;

function sendDTMF(optionDigit,phoneNumber) {
            cidDTMF = phoneNumber;
            oDigit = optionDigit;
            viciChannel = parent.document.getElementById('xferchannel').value;
            dCount = 0;
            xTones = 0;
            astmanEngine.setURL('../asterisk/rawman/?');
            astmanEngine.setEventCallback();
            astmanEngine.sendRequest('action=login&username=user&secret=secret', ajam.sendDigits);
      }

ajam.SendDTMF = function() {
       if (xTones > numTones) return;// stop
      if (dCount > 0) {
            singleDigit = String(cidDTMF).charAt(xTones);
             astmanEngine.sendRequest('action=PlayDTMF&Channel='  + viciChannel + '&Digit=' + singleDigit);
             setTimeout('ajam.SendDTMF()',500);
             xTones++;
      }
      else if (dCount == 0) {
            astmanEngine.sendRequest('action=PlayDTMF&Channel='  + viciChannel + '&Digit=' + oDigit);
            setTimeout('ajam.SendDTMF()',500);
            dCount++;
      }
0
Michel PlungjanIT ExpertCommented:
Okee, glad it worked.
I have a suspicion that we should have used the setEventCallBack to the continuation of the call. But if this works it works

Michel
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
IP Telephony

From novice to tech pro — start learning today.