2718.us blog » asterisk http://2718.us/blog Miscellaneous Technological Geekery Tue, 18 May 2010 02:42:55 +0000 en hourly 1 http://wordpress.org/?v=3.0.4 More Hackery with Slug Asterisk http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/ http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/#comments Mon, 18 Aug 2008 05:29:32 +0000 2718.us http://2718.us/blog/?p=95 I wanted to make my slug running Asterisk do wakeup calls, since I currently pay $11/month for a daily wakeup call service and they’ll only try up to 4 times.  As my starting point, I was using this dialplan from the-asterisk-book.com:

  1. [hotel-intern]
  2. exten => _*77*XXXXXXXXXXXX,1,Answer()
  3. exten => _*77*XXXXXXXXXXXX,n,Set(year=${EXTEN:4:4})
  4. exten => _*77*XXXXXXXXXXXX,n,Set(month=${EXTEN:8:2})
  5. exten => _*77*XXXXXXXXXXXX,n,Set(day=${EXTEN:10:2})
  6. exten => _*77*XXXXXXXXXXXX,n,Set(hours=${EXTEN:12:2})
  7. exten => _*77*XXXXXXXXXXXX,n,Set(minutes=${EXTEN:14:2})
  8. exten => _*77*XXXXXXXXXXXX,n,NoOp(Wake-up call scheduled for ${CALLERID(num)} at ${hours}:${minutes} on ${day}.${month}.${year}.)
  9. exten => _*77*XXXXXXXXXXXX,n,System(echo -e "Channel: SIP/${CALLERID(num)}\\nContext: wake-up\\nExtension: 23" > /tmp/${UNIQUEID}.call)
  10. exten => _*77*XXXXXXXXXXXX,n,System(touch -t ${year}${month}${day}${hours}${minutes} /tmp/${UNIQUEID}.call)
  11. exten => _*77*XXXXXXXXXXXX,n,System(mv /tmp/${UNIQUEID}.call /var/spool/asterisk/outgoing/)
  12. exten => _*77*XXXXXXXXXXXX,n,Playback(rqsted-wakeup-for)
  13. exten => _*77*XXXXXXXXXXXX,n,SayNumber(${hours})
  14. exten => _*77*XXXXXXXXXXXX,n,SayNumber(${minutes})
  15. exten => _*77*XXXXXXXXXXXX,n,Hangup()
  16.  
  17. [wake-up]
  18. exten => 23,1,Answer()
  19. exten => 23,n,Wait(1)
  20. exten => 23,n,Playback(this-is-yr-wakeup-call)
  21. exten => 23,n,Wait(1)
  22. exten => 23,n,Hangup()

The problem is that my slug is unslung, running busybox for most basic *nix tools and busybox’s touch command doesn’t support the -t option, so I can’t set the modification time on the file to properly queue it.  My half-assed workaround is a shell script (because I couldn’t get the System() command to run the whole string, try as I might) that nohups a background shell process that sleeps for the difference in seconds between now and the wakeup time, then creates the call file.  Not great for far-future scheduling or for large numbers of calls and it won’t survive a reboot, but it’s a start.

#!/bin/sh
  1.  
  2. nohup sh -c "sleep $((`/bin/date –date="$1" +"%s"` – `/bin/date +"%s"`)) ; echo -e 'Channel: $2\\nContext: wake-up\\nExtension: 23' > /tmp/$3.call ; mv /tmp/$3.call /opt/var/spool/asterisk/outgoing/" >/dev/null &

My Asterisk diaplan macro passes the target time/date string as the first argument, the target channel as the second, and the ${UNIQUEID} as the third.  One further wrinkle:  busybox 1.3.1, which was what came with the unslung firmware I used, doesn’t have nohup, so it won’t work; busybox 1.10.3 is what ipkg installed into /opt/ and has nohup, but the date command in 1.10.3 didn’t seem to support –date (at all, or maybe just not properly), so nohup is a reference to the 1.10.3 busybox in /opt/bin while /bin/date is a reference to the original 1.3.1 busybox.  Stupid, but it works.

(Oh, and as I told the last person I saw wearing a t-shirt that said “If it’s stupid, but it works, then it isn’t stupid,” there’s definitely such a thing as works-but-stupid–this script hackery is such a thing.  The better solution, space permitting, is probably just to install the coreutils package so as to have proper non-busybox touch and date)

]]>
http://2718.us/blog/2008/08/18/more-hackery-with-slug-asterisk/feed/ 0
Converting to Asterisk-Native SLN Audio with ffmpeg http://2718.us/blog/2008/07/21/converting-to-asterisk-native-sln-audio-with-ffmpeg/ http://2718.us/blog/2008/07/21/converting-to-asterisk-native-sln-audio-with-ffmpeg/#comments Mon, 21 Jul 2008 13:31:00 +0000 2718.us http://2718.us/blog/?p=62 I have spent a large chunk of the past two weekends trying to find some kind of instructions as to how to get audio into the native Asterisk “SLN” format.  Specifically, I wanted to convert some mp3s of classical music (such as from Musopen) to SLN for music-on-hold.  I was able to discern that SLN files are “raw” or headerless “wav” format, 16-bit signed PCM or signed linear (hence SLN).  After several attempts to convert mp3s, wavs, and other things to this format, only to have them play as painfully loud static, I tried reversing the process and importing some working sample SLN files in Audacity.  This led to the big ah-ha! moment of the weekend—the Asterisk SLN files are 16-bit little-endian signed PCM, whereas SoX, Audacity, et al, were putting out big-endian 16-bit signed PCM.  I couldn’t for the life of me find an option to change the endiannes in Audacity, however.

In searching some more, I found that ffmpeg, one of the best swiss-army-knife-type audio/video conversion programs, specifically supports signed 16-bit little-endian PCM.  Here’s the command to convert just about any audio (anything ffmpeg can handle) to the appropriate format for Asterisk music-on-hold:

ffmpeg -i "[input file]" -ar 8000 -ac 1 -acodec pcm_s16le -f s16le "[output file].sln"

You may also want to add a volume modifier, to make the music appropriately quiet for music-on-hold, and ffmpeg allows this to be specified in dB gain like “-vol -15dB”.

]]>
http://2718.us/blog/2008/07/21/converting-to-asterisk-native-sln-audio-with-ffmpeg/feed/ 2
Simple Weather in Asterisk with Minimal Tools http://2718.us/blog/2008/07/20/simple-weather-in-asterisk-with-minimal-tools/ http://2718.us/blog/2008/07/20/simple-weather-in-asterisk-with-minimal-tools/#comments Sun, 20 Jul 2008 12:02:20 +0000 2718.us http://2718.us/blog/?p=54 I’ve been fiddling around with Asterisk on a slug box.  It’s working pretty well, but since I don’t want to deal with compiling things for the slug, I’m limited to the Asterisk modules that are available as binaries (not many).  I’m also using the older Asterisk 1.2.  This has led to some interesting hacks to make things happen. The end result of a lot of this hacking is a dialplan-shellscript-sed combo to read out some basic weather forecast info acquired from Yahoo.

First, the dialplan.

  1. exten => s,1,Set(defaultWeatherZip=10001)
  2. exten => s,n,Playback(please-enter-your&zip-code)
  3. exten => s,n,Read(zip||5)
  4. exten => s,n,GotoIf($[${LEN(${zip})} = 5]?getweather)
  5. exten => s,n,Set(zip=${defaultWeatherZip})
  6. exten => s,n(getweather),System(get_weather.sh ${zip} > /tmp/weather-${UNIQUEID}.tmp)
  7. exten => s,n,Readfile(weather=/tmp/weather-${UNIQUEID}.tmp,300)
  8. exten => s,n,Playback(weather&for&zip-code)
  9. exten => s,n,SayDigits(${zip})
  10. exten => s,n,Playback(silence/1&${weather}&silence/1)
  11. exten => s,n,System(rm /tmp/weather-${UNIQUEID}.tmp)

If you’ve got a text-to-speech engine and can create smoother strings of spoken words than what I’ve strung together here, you’re better off (on my Asterisk box, I’m actually using files I made with Cepstral’s Allison-8k running on my Mac).  With my limited command set, there’s no nice way to grab the output of a system command, so I capture it into a temp file, use ReadFile() on the temp file, then delete the temp file.

That dialplan called a shellscript, get_weather.sh:

#!/bin/sh
  1. echo -n
  2.  `curl –silent http://weather.yahooapis.com/forecastrss?p=$1
  3.   | sed -n -f /opt/var/lib/asterisk/yahoo_weather_to_asterisk.sed
  4.   | sed -e 'N;s/(.*)n(.*)/1&silence/2&2/'`

This uses curl to get the weather from Yahoo, runs it through a complicated sed program which yields two lines of forecast (as &-joined lists of sound files, suitable for running as an argument to Playback() in Asterisk), then joins the two lines with 2 seconds of silence. The “echo -n `…`” is a trick for stripping the trailing newline from the output of curl/sed (a newline inside the Playback() get interpreted as part of the filename, which it isn’t).

Finally, the sed program that processes the output from Yahoo:

  1. /^<yweather :forecast/{
  2.  # replace days with sound files
  3.  s/Mon/day-1/
  4.  s/Tue/day-2/
  5.  s/Wed/day-3/
  6.  s/Thu/day-4/
  7.  s/Fri/day-5/
  8.  s/Sat/day-6/
  9.  s/Sun/day-0/
  10.  
  11.  # replace months with sound files
  12.  s/Jan/mon-0/
  13.  s/Feb/mon-1/
  14.  s/Mar/mon-2/
  15.  s/Apr/mon-3/
  16.  s/May/mon-4/
  17.  s/Jun/mon-5/
  18.  s/Jul/mon-6/
  19.  s/Aug/mon-7/
  20.  s/Sep/mon-8/
  21.  s/Oct/mon-9/
  22.  s/Nov/mon-10/
  23.  s/Dec/mon-11/
  24.  
  25.  # rearrange forecast lines
  26.  s/^<yweather:forecast day="(day-[0-6])" date="([0-9]*) (mon-[0-9]*) ([0-9]*)" low="([0-9]*)" high="([0-9]*)" .*/>/digits/1&digits/3&DATE-2&silence/1&high&TEMP-6&silence/1&low&TEMP-5/
  27.  
  28.  # replace the date with proper ordinal sound files
  29.  # thirty + one is a special case
  30.  s/DATE-31/digits/30&digits/h-1/
  31.  # twenty + [1-9]
  32.  s/DATE-2([1-9])/digits/20&digits/h-1/
  33.  # 1-20,30 all have their own files
  34.  s/DATE-([0-9]*)/digits/h-1/
  35.  
  36.  # negative temps
  37.  s/TEMP–/minus&TEMP-/g
  38.  
  39.  # 100 is a special case
  40.  s/TEMP-100/digits/1&digits/hundred/g
  41.  # 10?
  42.  s/TEMP-10([1-9])/digits/1&digits/hundred&digits/1/g
  43.  # 11?
  44.  s/TEMP-11([0-9])/digits/1&digits/hundred&digits/11/g
  45.  # 1?0
  46.  s/TEMP-1([2-9])0/digits/1&digits/hundred&digits/10/g
  47.  # 1??
  48.  s/TEMP-1([2-9])([1-9])/digits/1&digits/hundred&digits/10&digits/2/g
  49.  # 1?
  50.  s/TEMP-1([0-9])/digits/11/g
  51.  # ?0
  52.  s/TEMP-([2-9])0/digits/10/g
  53.  # ??
  54.  s/TEMP-([2-9])([1-9])/digits/10&digits/2/g
  55.  # ?
  56.  s/TEMP-([0-9])/digits/1/g
  57.  
  58.  p
  59. }

The “rearrange” line does most of the work of taking apart the last bits of what Yahoo gave us; the rest of the sed program is dominated by converting months/days/numbers into references to the appropriate Asterisk sound files. [Note: Since I only had today's data with which to work, I made some guesses as to what the shortened forms of most of the months and days would be, as well as how temperatures that weren't two-digit positive numbers would be presented.]

]]>
http://2718.us/blog/2008/07/20/simple-weather-in-asterisk-with-minimal-tools/feed/ 0