head 1.1; access; symbols; locks; strict; comment @# @; 1.1 date 2008.03.24.20.03.51; author rse; state Exp; branches; next ; commitid j6x4ujLB3SG6SpWs; desc @@ 1.1 log @new package: asterisk-utils 0 (Asterisk Addon Utilities) @ text @#!/usr/bin/perl ## ## asterisk-clock.pl -- Asterisk PBX Accurate Talking Clock ## Copyright (c) 2007 Chris Walton ## Copyright (c) 2008 Ralf S. Engelschall ## License: GPL (version 2 or higher) ## ## This script will generate a 1.5s beep at 0, 15, 30, and 45 seconds ## past each minute. It uses sub-second time delays in order to be as ## accurate as possible. The time is annoumced in English at 11 seconds ## before the beep. Warning "blips" play and 2 seconds and 1 second ## before the beep. ## ## 1st PASS example... assume program starts at 5.5 seconds past the minute: ## ---------------------------------------------------------------------------- ## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ## ->BLIP>BLIP>BLIP>BLIP>BLIP>BLIP>BLI>BLIP>BLIP>BEEP ## normal operation (loop): ## ---------------------------------------------------------------------------- ## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ## BEEP--->SILENCE----->TIME_ANNOUNCEMENT_FOLLOWED_BY_SILENCE----->BLIP>BLIP>BEEP ## use Time::HiRes qw(usleep gettimeofday); my $blip = "!523/20,!0/980"; # 20ms blip followed by 980ms silence. my $beep = "!415/1500"; # 1.5s beep. my $silence = "!0/500"; # 0.5s silence. # turn off output buffering to stop dead lock. $| = 1; sub status { # AGI function status is avaialbe on STDIN my $cmd = shift; my $status = ; if ($status !~ m/^200 result=0/) { print STDERR "$cmd returned with bad status ($status)\n"; exit(-1); } } # STDIN will initially contain assorted channel information. Discard it all. while () { chomp; last unless ($_); } # Answer the channel print "ANSWER\n"; status("Exec Answer"); while (1) { my ($seconds, $microseconds) = gettimeofday(); # sleep until the next second rolls around. usleep(1000000 - $microseconds); # calculate number of seconds left before the beep. my $time_til_beep = 14 - ($seconds % 15); if ($time_til_beep < 11 ) { # Insufficient time to announce the time; just play blips. # This should only occur on first pass. print "EXEC PlayTones ", ("$blip," x $time_til_beep), $beep, "\n"; status("Exec PlayTones"); # Sleep while the blips and beep are playing. usleep($time_til_beep * 1000000 + 1500000); } else { # We have sufficient time to announce what the time will be at the beep. my $time_at_beep = $seconds + $time_til_beep + 1; # Sleep until 11 seconds before the beep and then announce the time. usleep(($time_til_beep - 11) * 1000000); print qq{STREAM FILE at-tone-time-exactly ""\n}; status("Stream File"); print qq{SAY DATETIME $time_at_beep "#" "IM'vm-and'S'seconds'\n}; status("Say DateTime"); # We need to get the time again because we don't know how long # the announcement took to play. ($seconds, $microseconds) = gettimeofday(); # Now sleep until 2.5 seconds before the beep. my $delay = 12500000 - $microseconds - (($seconds % 15) * 1000000); next if ($delay < 0); # abort if annoucment took too long to play. usleep($delay); # Now play two warning blips followed by the beep. # Preceeding the blips with .5s silence ensures the 1st blip is heard. print "EXEC PlayTones $silence,$blip,$blip,$beep\n"; status("Exec PlayTones"); # Sleep while the blips and beep are playing. usleep(4000000); } } @