PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/phpagi-2.14/phpagi.php

https://github.com/Synforge/SynIVR
PHP | 1740 lines | 1558 code | 33 blank | 149 comment | 18 complexity | a2d28eb567bfa13acc9022fef9f77961 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * phpagi.php : PHP AGI Functions for Asterisk
  4. * Website: http://phpagi.sourceforge.net/
  5. *
  6. * $Id: phpagi.php,v 2.14 2005/05/25 20:30:46 pinhole Exp $
  7. *
  8. * Copyright (c) 2003, 2004, 2005 Matthew Asham <matthewa@bcwireless.net>, David Eder <david@eder.us>
  9. * All Rights Reserved.
  10. *
  11. * This software is released under the terms of the GNU Lesser General Public License v2.1
  12. * A copy of which is available from http://www.gnu.org/copyleft/lesser.html
  13. *
  14. * We would be happy to list your phpagi based application on the phpagi
  15. * website. Drop me an Email if you'd like us to list your program.
  16. *
  17. *
  18. * Written for PHP 4.3.4, should work with older PHP 4.x versions.
  19. *
  20. * Please submit bug reports, patches, etc to http://sourceforge.net/projects/phpagi/
  21. * Gracias. :)
  22. *
  23. *
  24. * @package phpAGI
  25. * @version 2.0
  26. */
  27. /**
  28. */
  29. if(!class_exists('AGI_AsteriskManager'))
  30. {
  31. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpagi-asmanager.php');
  32. }
  33. define('AST_CONFIG_DIR', '/etc/asterisk/');
  34. define('AST_SPOOL_DIR', '/var/spool/asterisk/');
  35. define('AST_TMP_DIR', AST_SPOOL_DIR . '/tmp/');
  36. define('DEFAULT_PHPAGI_CONFIG', AST_CONFIG_DIR . '/phpagi.conf');
  37. define('AST_DIGIT_ANY', '0123456789#*');
  38. define('AGIRES_OK', 200);
  39. define('AST_STATE_DOWN', 0);
  40. define('AST_STATE_RESERVED', 1);
  41. define('AST_STATE_OFFHOOK', 2);
  42. define('AST_STATE_DIALING', 3);
  43. define('AST_STATE_RING', 4);
  44. define('AST_STATE_RINGING', 5);
  45. define('AST_STATE_UP', 6);
  46. define('AST_STATE_BUSY', 7);
  47. define('AST_STATE_DIALING_OFFHOOK', 8);
  48. define('AST_STATE_PRERING', 9);
  49. define('AUDIO_FILENO', 3); // STDERR_FILENO + 1
  50. /**
  51. * AGI class
  52. *
  53. * @package phpAGI
  54. * @link http://www.voip-info.org/wiki-Asterisk+agi
  55. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  56. * @example examples/input.php Get text input from the user and say it back
  57. * @example examples/ping.php Ping an IP address
  58. */
  59. class AGI
  60. {
  61. /**
  62. * Request variables read in on initialization.
  63. *
  64. * Often contains any/all of the following:
  65. * agi_request - name of agi script
  66. * agi_channel - current channel
  67. * agi_language - current language
  68. * agi_type - channel type (SIP, ZAP, IAX, ...)
  69. * agi_uniqueid - unique id based on unix time
  70. * agi_callerid - callerID string
  71. * agi_dnid - dialed number id
  72. * agi_rdnis - referring DNIS number
  73. * agi_context - current context
  74. * agi_extension - extension dialed
  75. * agi_priority - current priority
  76. * agi_enhanced - value is 1.0 if started as an EAGI script
  77. * agi_accountcode - set by SetAccount in the dialplan
  78. * agi_network - value is yes if this is a fastagi
  79. * agi_network_script - name of the script to execute
  80. *
  81. * NOTE: program arguments are still in $_SERVER['argv'].
  82. *
  83. * @var array
  84. * @access public
  85. */
  86. var $request;
  87. /**
  88. * Config variables
  89. *
  90. * @var array
  91. * @access public
  92. */
  93. var $config;
  94. /**
  95. * Asterisk Manager
  96. *
  97. * @var AGI_AsteriskManager
  98. * @access public
  99. */
  100. var $asmanager;
  101. /**
  102. * Input Stream
  103. *
  104. * @access private
  105. */
  106. var $in = NULL;
  107. /**
  108. * Output Stream
  109. *
  110. * @access private
  111. */
  112. var $out = NULL;
  113. /**
  114. * Audio Stream
  115. *
  116. * @access public
  117. */
  118. var $audio = NULL;
  119. /**
  120. * Constructor
  121. *
  122. * @param string $config is the name of the config file to parse
  123. * @param array $optconfig is an array of configuration vars and vals, stuffed into $this->config['phpagi']
  124. */
  125. function AGI($config=NULL, $optconfig=array())
  126. {
  127. // load config
  128. if(!is_null($config) && file_exists($config))
  129. $this->config = parse_ini_file($config, true);
  130. elseif(file_exists(DEFAULT_PHPAGI_CONFIG))
  131. $this->config = parse_ini_file(DEFAULT_PHPAGI_CONFIG, true);
  132. // If optconfig is specified, stuff vals and vars into 'phpagi' config array.
  133. foreach($optconfig as $var=>$val)
  134. $this->config['phpagi'][$var] = $val;
  135. // add default values to config for uninitialized values
  136. if(!isset($this->config['phpagi']['error_handler'])) $this->config['phpagi']['error_handler'] = true;
  137. if(!isset($this->config['phpagi']['debug'])) $this->config['phpagi']['debug'] = false;
  138. if(!isset($this->config['phpagi']['admin'])) $this->config['phpagi']['admin'] = NULL;
  139. if(!isset($this->config['phpagi']['tempdir'])) $this->config['phpagi']['tempdir'] = AST_TMP_DIR;
  140. // festival TTS config
  141. if(!isset($this->config['festival']['text2wave'])) $this->config['festival']['text2wave'] = $this->which('text2wave');
  142. // swift TTS config
  143. if(!isset($this->config['cepstral']['swift'])) $this->config['cepstral']['swift'] = $this->which('swift');
  144. ob_implicit_flush(true);
  145. // open stdin & stdout
  146. $this->in = defined('STDIN') ? STDIN : fopen('php://stdin', 'r');
  147. $this->out = defined('STDOUT') ? STDOUT : fopen('php://stdout', 'w');
  148. // initialize error handler
  149. if($this->config['phpagi']['error_handler'] == true)
  150. {
  151. set_error_handler('phpagi_error_handler');
  152. global $phpagi_error_handler_email;
  153. $phpagi_error_handler_email = $this->config['phpagi']['admin'];
  154. error_reporting(E_ALL);
  155. }
  156. // make sure temp folder exists
  157. $this->make_folder($this->config['phpagi']['tempdir']);
  158. // read the request
  159. $str = fgets($this->in);
  160. while($str != "\n")
  161. {
  162. $this->request[substr($str, 0, strpos($str, ':'))] = trim(substr($str, strpos($str, ':') + 1));
  163. $str = fgets($this->in);
  164. }
  165. // open audio if eagi detected
  166. if($this->request['agi_enhanced'] == '1.0')
  167. {
  168. if(file_exists('/proc/' . getmypid() . '/fd/3'))
  169. $this->audio = fopen('/proc/' . getmypid() . '/fd/3', 'r');
  170. elseif(file_exists('/dev/fd/3'))
  171. {
  172. // may need to mount fdescfs
  173. $this->audio = fopen('/dev/fd/3', 'r');
  174. }
  175. else
  176. $this->conlog('Unable to open audio stream');
  177. if($this->audio) stream_set_blocking($this->audio, 0);
  178. }
  179. $this->conlog('AGI Request:');
  180. $this->conlog(print_r($this->request, true));
  181. $this->conlog('PHPAGI internal configuration:');
  182. $this->conlog(print_r($this->config, true));
  183. }
  184. // *********************************************************************************************************
  185. // ** COMMANDS **
  186. // *********************************************************************************************************
  187. /**
  188. * Answer channel if not already in answer state.
  189. *
  190. * @link http://www.voip-info.org/wiki-answer
  191. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  192. * @example examples/input.php Get text input from the user and say it back
  193. * @example examples/ping.php Ping an IP address
  194. *
  195. * @return array, see evaluate for return information. ['result'] is 0 on success, -1 on failure.
  196. */
  197. function answer()
  198. {
  199. return $this->evaluate('ANSWER');
  200. }
  201. /**
  202. * Get the status of the specified channel. If no channel name is specified, return the status of the current channel.
  203. *
  204. * @link http://www.voip-info.org/wiki-channel+status
  205. * @param string $channel
  206. * @return array, see evaluate for return information. ['data'] contains description.
  207. */
  208. function channel_status($channel='')
  209. {
  210. $ret = $this->evaluate("CHANNEL STATUS $channel");
  211. switch($ret['result'])
  212. {
  213. case -1: $ret['data'] = trim("There is no channel that matches $channel"); break;
  214. case AST_STATE_DOWN: $ret['data'] = 'Channel is down and available'; break;
  215. case AST_STATE_RESERVED: $ret['data'] = 'Channel is down, but reserved'; break;
  216. case AST_STATE_OFFHOOK: $ret['data'] = 'Channel is off hook'; break;
  217. case AST_STATE_DIALING: $ret['data'] = 'Digits (or equivalent) have been dialed'; break;
  218. case AST_STATE_RING: $ret['data'] = 'Line is ringing'; break;
  219. case AST_STATE_RINGING: $ret['data'] = 'Remote end is ringing'; break;
  220. case AST_STATE_UP: $ret['data'] = 'Line is up'; break;
  221. case AST_STATE_BUSY: $ret['data'] = 'Line is busy'; break;
  222. case AST_STATE_DIALING_OFFHOOK: $ret['data'] = 'Digits (or equivalent) have been dialed while offhook'; break;
  223. case AST_STATE_PRERING: $ret['data'] = 'Channel has detected an incoming call and is waiting for ring'; break;
  224. default: $ret['data'] = "Unknown ({$ret['result']})"; break;
  225. }
  226. return $ret;
  227. }
  228. /**
  229. * Deletes an entry in the Asterisk database for a given family and key.
  230. *
  231. * @link http://www.voip-info.org/wiki-database+del
  232. * @param string $family
  233. * @param string $key
  234. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
  235. */
  236. function database_del($family, $key)
  237. {
  238. return $this->evaluate("DATABASE DEL \"$family\" \"$key\"");
  239. }
  240. /**
  241. * Deletes a family or specific keytree within a family in the Asterisk database.
  242. *
  243. * @link http://www.voip-info.org/wiki-database+deltree
  244. * @param string $family
  245. * @param string $keytree
  246. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise.
  247. */
  248. function database_deltree($family, $keytree='')
  249. {
  250. $cmd = "DATABASE DELTREE \"$family\"";
  251. if($keytree != '') $cmd .= " \"$keytree\"";
  252. return $this->evaluate($cmd);
  253. }
  254. /**
  255. * Retrieves an entry in the Asterisk database for a given family and key.
  256. *
  257. * @link http://www.voip-info.org/wiki-database+get
  258. * @param string $family
  259. * @param string $key
  260. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 failure. ['data'] holds the value
  261. */
  262. function database_get($family, $key)
  263. {
  264. return $this->evaluate("DATABASE GET \"$family\ \"$key\"");
  265. }
  266. /**
  267. * Adds or updates an entry in the Asterisk database for a given family, key, and value.
  268. *
  269. * @param string $family
  270. * @param string $key
  271. * @param string $value
  272. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 otherwise
  273. */
  274. function database_put($family, $key, $value)
  275. {
  276. $value = str_replace("\n", '\n', addslashes($value));
  277. return $this->evaluate("DATABASE PUT \"$family\" \"$key\" \"$value\"");
  278. }
  279. /**
  280. * Executes the specified Asterisk application with given options.
  281. *
  282. * @link http://www.voip-info.org/wiki-exec
  283. * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
  284. * @param string $application
  285. * @param mixed $options
  286. * @return array, see evaluate for return information. ['result'] is whatever the application returns, or -2 on failure to find application
  287. */
  288. function exec($application, $options)
  289. {
  290. if(is_array($options)) $options = join('|', $options);
  291. return $this->evaluate("EXEC $application $options");
  292. }
  293. /**
  294. * Plays the given file and receives DTMF data.
  295. *
  296. * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
  297. * while STREAM FILE returns immediately after the first DTMF digit is detected.
  298. *
  299. * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
  300. *
  301. * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
  302. * of silence then the command ends.
  303. *
  304. * The user has the opportunity to press a key at any time during the message or the
  305. * post-message silence. If the user presses a key while the message is playing, the
  306. * message stops playing. When the first key is pressed a timer starts counting for
  307. * $timeout milliseconds. Every time the user presses another key the timer is restarted.
  308. * The command ends when the counter goes to zero or the maximum number of digits is entered,
  309. * whichever happens first.
  310. *
  311. * If you don't specify a time out then a default timeout of 2000 is used following a pressed
  312. * digit. If no digits are pressed then 6 seconds of silence follow the message.
  313. *
  314. * If you don't specify $max_digits then the user can enter as many digits as they want.
  315. *
  316. * Pressing the # key has the same effect as the timer running out: the command ends and
  317. * any previously keyed digits are returned. A side effect of this is that there is no
  318. * way to read a # key using this command.
  319. *
  320. * @example examples/ping.php Ping an IP address
  321. *
  322. * @link http://www.voip-info.org/wiki-get+data
  323. * @param string $filename file to play. Do not include file extension.
  324. * @param integer $timeout milliseconds
  325. * @param integer $max_digits
  326. * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
  327. *
  328. * This differs from other commands with return DTMF as numbers representing ASCII characters.
  329. */
  330. function get_data($filename, $timeout=NULL, $max_digits=NULL)
  331. {
  332. return $this->evaluate(rtrim("GET DATA $filename $timeout $max_digits"));
  333. }
  334. /**
  335. * Fetch the value of a variable.
  336. *
  337. * Does not work with global variables. Does not work with some variables that are generated by modules.
  338. *
  339. * @link http://www.voip-info.org/wiki-get+variable
  340. * @link http://www.voip-info.org/wiki-Asterisk+variables
  341. * @param string $variable name
  342. * @return array, see evaluate for return information. ['result'] is 0 if variable hasn't been set, 1 if it has. ['data'] holds the value.
  343. */
  344. function get_variable($variable)
  345. {
  346. return $this->evaluate("GET VARIABLE $variable");
  347. }
  348. /**
  349. * Hangup the specified channel. If no channel name is given, hang up the current channel.
  350. *
  351. * With power comes responsibility. Hanging up channels other than your own isn't something
  352. * that is done routinely. If you are not sure why you are doing so, then don't.
  353. *
  354. * @link http://www.voip-info.org/wiki-hangup
  355. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  356. * @example examples/input.php Get text input from the user and say it back
  357. * @example examples/ping.php Ping an IP address
  358. *
  359. * @param string $channel
  360. * @return array, see evaluate for return information. ['result'] is 1 on success, -1 on failure.
  361. */
  362. function hangup($channel='')
  363. {
  364. return $this->evaluate("HANGUP $channel");
  365. }
  366. /**
  367. * Does nothing.
  368. *
  369. * @link http://www.voip-info.org/wiki-noop
  370. * @return array, see evaluate for return information.
  371. */
  372. function noop()
  373. {
  374. return $this->evaluate('NOOP');
  375. }
  376. /**
  377. * Receive a character of text from a connected channel. Waits up to $timeout milliseconds for
  378. * a character to arrive, or infinitely if $timeout is zero.
  379. *
  380. * @link http://www.voip-info.org/wiki-receive+char
  381. * @param integer $timeout milliseconds
  382. * @return array, see evaluate for return information. ['result'] is 0 on timeout or not supported, -1 on failure. Otherwise
  383. * it is the decimal value of the DTMF tone. Use chr() to convert to ASCII.
  384. */
  385. function receive_char($timeout=-1)
  386. {
  387. return $this->evaluate("RECEIVE CHAR $timeout");
  388. }
  389. /**
  390. * Record sound to a file until an acceptable DTMF digit is received or a specified amount of
  391. * time has passed. Optionally the file BEEP is played before recording begins.
  392. *
  393. * @link http://www.voip-info.org/wiki-record+file
  394. * @param string $file to record, without extension, often created in /var/lib/asterisk/sounds
  395. * @param string $format of the file. GSM and WAV are commonly used formats. MP3 is read-only and thus cannot be used.
  396. * @param string $escape_digits
  397. * @param integer $timeout is the maximum record time in milliseconds, or -1 for no timeout.
  398. * @param integer $offset to seek to without exceeding the end of the file.
  399. * @param boolean $beep
  400. * @param integer $silence number of seconds of silence allowed before the function returns despite the
  401. * lack of dtmf digits or reaching timeout.
  402. * @return array, see evaluate for return information. ['result'] is -1 on error, 0 on hangup, otherwise a decimal value of the
  403. * DTMF tone. Use chr() to convert to ASCII.
  404. */
  405. function record_file($file, $format, $escape_digits='', $timeout=-1, $offset=NULL, $beep=false, $silence=NULL)
  406. {
  407. $cmd = trim("RECORD FILE $file $format \"$escape_digits\" $timeout $offset");
  408. if($beep) $cmd .= ' BEEP';
  409. if(!is_null($silence)) $cmd .= " s=$silence";
  410. return $this->evaluate($cmd);
  411. }
  412. /**
  413. * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
  414. *
  415. * @link http://www.voip-info.org/wiki-say+digits
  416. * @param integer $digits
  417. * @param string $escape_digits
  418. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  419. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  420. */
  421. function say_digits($digits, $escape_digits='')
  422. {
  423. return $this->evaluate("SAY DIGITS $digits \"$escape_digits\"");
  424. }
  425. /**
  426. * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
  427. *
  428. * @link http://www.voip-info.org/wiki-say+number
  429. * @param integer $number
  430. * @param string $escape_digits
  431. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  432. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  433. */
  434. function say_number($number, $escape_digits='')
  435. {
  436. return $this->evaluate("SAY NUMBER $number \"$escape_digits\"");
  437. }
  438. /**
  439. * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
  440. *
  441. * @link http://www.voip-info.org/wiki-say+phonetic
  442. * @param string $text
  443. * @param string $escape_digits
  444. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  445. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  446. */
  447. function say_phonetic($text, $escape_digits='')
  448. {
  449. return $this->evaluate("SAY PHONETIC $text \"$escape_digits\"");
  450. }
  451. /**
  452. * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
  453. *
  454. * @link http://www.voip-info.org/wiki-say+time
  455. * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
  456. * @param string $escape_digits
  457. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  458. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  459. */
  460. function say_time($time=NULL, $escape_digits='')
  461. {
  462. if(is_null($time)) $time = time();
  463. return $this->evaluate("SAY TIME $time \"$escape_digits\"");
  464. }
  465. /**
  466. * Send the specified image on a channel.
  467. *
  468. * Most channels do not support the transmission of images.
  469. *
  470. * @link http://www.voip-info.org/wiki-send+image
  471. * @param string $image without extension, often in /var/lib/asterisk/images
  472. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the image is sent or
  473. * channel does not support image transmission.
  474. */
  475. function send_image($image)
  476. {
  477. return $this->evaluate("SEND IMAGE $image");
  478. }
  479. /**
  480. * Send the given text to the connected channel.
  481. *
  482. * Most channels do not support transmission of text.
  483. *
  484. * @link http://www.voip-info.org/wiki-send+text
  485. * @param $text
  486. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if the text is sent or
  487. * channel does not support text transmission.
  488. */
  489. function send_text($text)
  490. {
  491. return $this->evaluate("SEND TEXT \"$text\"");
  492. }
  493. /**
  494. * Cause the channel to automatically hangup at $time seconds in the future.
  495. * If $time is 0 then the autohangup feature is disabled on this channel.
  496. *
  497. * If the channel is hungup prior to $time seconds, this setting has no effect.
  498. *
  499. * @link http://www.voip-info.org/wiki-set+autohangup
  500. * @param integer $time until automatic hangup
  501. * @return array, see evaluate for return information.
  502. */
  503. function set_autohangup($time=0)
  504. {
  505. return $this->evaluate("SET AUTOHANGUP $time");
  506. }
  507. /**
  508. * Changes the caller ID of the current channel.
  509. *
  510. * @link http://www.voip-info.org/wiki-set+callerid
  511. * @param string $cid example: "John Smith"<1234567>
  512. * This command will let you take liberties with the <caller ID specification> but the format shown in the example above works
  513. * well: the name enclosed in double quotes followed immediately by the number inside angle brackets. If there is no name then
  514. * you can omit it. If the name contains no spaces you can omit the double quotes around it. The number must follow the name
  515. * immediately; don't put a space between them. The angle brackets around the number are necessary; if you omit them the
  516. * number will be considered to be part of the name.
  517. * @return array, see evaluate for return information.
  518. */
  519. function set_callerid($cid)
  520. {
  521. return $this->evaluate("SET CALLERID $cid");
  522. }
  523. /**
  524. * Sets the context for continuation upon exiting the application.
  525. *
  526. * Setting the context does NOT automatically reset the extension and the priority; if you want to start at the top of the new
  527. * context you should set extension and priority yourself.
  528. *
  529. * If you specify a non-existent context you receive no error indication (['result'] is still 0) but you do get a
  530. * warning message on the Asterisk console.
  531. *
  532. * @link http://www.voip-info.org/wiki-set+context
  533. * @param string $context
  534. * @return array, see evaluate for return information.
  535. */
  536. function set_context($context)
  537. {
  538. return $this->evaluate("SET CONTEXT $context");
  539. }
  540. /**
  541. * Set the extension to be used for continuation upon exiting the application.
  542. *
  543. * Setting the extension does NOT automatically reset the priority. If you want to start with the first priority of the
  544. * extension you should set the priority yourself.
  545. *
  546. * If you specify a non-existent extension you receive no error indication (['result'] is still 0) but you do
  547. * get a warning message on the Asterisk console.
  548. *
  549. * @link http://www.voip-info.org/wiki-set+extension
  550. * @param string $extension
  551. * @return array, see evaluate for return information.
  552. */
  553. function set_extension($extension)
  554. {
  555. return $this->evaluate("SET EXTENSION $extension");
  556. }
  557. /**
  558. * Enable/Disable Music on hold generator.
  559. *
  560. * @link http://www.voip-info.org/wiki-set+music
  561. * @param boolean $enabled
  562. * @param string $class
  563. * @return array, see evaluate for return information.
  564. */
  565. function set_music($enabled=true, $class='')
  566. {
  567. $enabled = ($enabled) ? 'ON' : 'OFF';
  568. return $this->evaluate("SET MUSIC $enabled $class");
  569. }
  570. /**
  571. * Set the priority to be used for continuation upon exiting the application.
  572. *
  573. * If you specify a non-existent priority you receive no error indication (['result'] is still 0)
  574. * and no warning is issued on the Asterisk console.
  575. *
  576. * @link http://www.voip-info.org/wiki-set+priority
  577. * @param integer $priority
  578. * @return array, see evaluate for return information.
  579. */
  580. function set_priority($priority)
  581. {
  582. return $this->evaluate("SET PRIORITY $priority");
  583. }
  584. /**
  585. * Sets a variable to the specified value. The variables so created can later be used by later using ${<variablename>}
  586. * in the dialplan.
  587. *
  588. * These variables live in the channel Asterisk creates when you pickup a phone and as such they are both local and temporary.
  589. * Variables created in one channel can not be accessed by another channel. When you hang up the phone, the channel is deleted
  590. * and any variables in that channel are deleted as well.
  591. *
  592. * @link http://www.voip-info.org/wiki-set+variable
  593. * @param string $variable is case sensitive
  594. * @param string $value
  595. * @return array, see evaluate for return information.
  596. */
  597. function set_variable($variable, $value)
  598. {
  599. $value = str_replace("\n", '\n', addslashes($value));
  600. return $this->evaluate("SET VARIABLE $variable \"$value\"");
  601. }
  602. /**
  603. * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
  604. * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
  605. * digits before returning.
  606. *
  607. * @example examples/ping.php Ping an IP address
  608. *
  609. * @link http://www.voip-info.org/wiki-stream+file
  610. * @param string $filename without extension, often in /var/lib/asterisk/sounds
  611. * @param string $escape_digits
  612. * @param integer $offset
  613. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  614. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  615. */
  616. function stream_file($filename, $escape_digits='', $offset=0)
  617. {
  618. return $this->evaluate("STREAM FILE $filename \"$escape_digits\" $offset");
  619. }
  620. /**
  621. * Enable or disable TDD transmission/reception on the current channel.
  622. *
  623. * @link http://www.voip-info.org/wiki-tdd+mode
  624. * @param string $setting can be on, off or mate
  625. * @return array, see evaluate for return information. ['result'] is 1 on sucess, 0 if the channel is not TDD capable.
  626. */
  627. function tdd_mode($setting)
  628. {
  629. return $this->evaluate("TDD MODE $setting");
  630. }
  631. /**
  632. * Sends $message to the Asterisk console via the 'verbose' message system.
  633. *
  634. * If the Asterisk verbosity level is $level or greater, send $message to the console.
  635. *
  636. * The Asterisk verbosity system works as follows. The Asterisk user gets to set the desired verbosity at startup time or later
  637. * using the console 'set verbose' command. Messages are displayed on the console if their verbose level is less than or equal
  638. * to desired verbosity set by the user. More important messages should have a low verbose level; less important messages
  639. * should have a high verbose level.
  640. *
  641. * @link http://www.voip-info.org/wiki-verbose
  642. * @param string $message
  643. * @param integer $level from 1 to 4
  644. * @return array, see evaluate for return information.
  645. */
  646. function verbose($message, $level=1)
  647. {
  648. foreach(explode("\n", str_replace("\r\n", "\n", print_r($message, true))) as $msg)
  649. {
  650. @syslog(LOG_WARNING, $msg);
  651. $ret = $this->evaluate("VERBOSE \"$msg\" $level");
  652. }
  653. return $ret;
  654. }
  655. /**
  656. * Waits up to $timeout milliseconds for channel to receive a DTMF digit.
  657. *
  658. * @link http://www.voip-info.org/wiki-wait+for+digit
  659. * @param integer $timeout in millisecons. Use -1 for the timeout value if you want the call to wait indefinitely.
  660. * @return array, see evaluate for return information. ['result'] is 0 if wait completes with no
  661. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  662. */
  663. function wait_for_digit($timeout=-1)
  664. {
  665. return $this->evaluate("WAIT FOR DIGIT $timeout");
  666. }
  667. // *********************************************************************************************************
  668. // ** APPLICATIONS **
  669. // *********************************************************************************************************
  670. /**
  671. * Set absolute maximum time of call.
  672. *
  673. * Note that the timeout is set from the current time forward, not counting the number of seconds the call has already been up.
  674. * Each time you call AbsoluteTimeout(), all previous absolute timeouts are cancelled.
  675. * Will return the call to the T extension so that you can playback an explanatory note to the calling party (the called party
  676. * will not hear that)
  677. *
  678. * @link http://www.voip-info.org/wiki-Asterisk+-+documentation+of+application+commands
  679. * @link http://www.dynx.net/ASTERISK/AGI/ccard/agi-ccard.agi
  680. * @param $seconds allowed, 0 disables timeout
  681. * @return array, see evaluate for return information.
  682. */
  683. function exec_absolutetimeout($seconds=0)
  684. {
  685. return $this->exec('AbsoluteTimeout', $seconds);
  686. }
  687. /**
  688. * Executes an AGI compliant application.
  689. *
  690. * @param string $command
  691. * @return array, see evaluate for return information. ['result'] is -1 on hangup or if application requested hangup, or 0 on non-hangup exit.
  692. * @param string $args
  693. */
  694. function exec_agi($command, $args)
  695. {
  696. return $this->exec("AGI $command", $args);
  697. }
  698. /**
  699. * Set Language.
  700. *
  701. * @param string $language code
  702. * @return array, see evaluate for return information.
  703. */
  704. function exec_setlanguage($language='en')
  705. {
  706. return $this->exec('SetLanguage', $language);
  707. }
  708. /**
  709. * Do ENUM Lookup.
  710. *
  711. * Note: to retrieve the result, use
  712. * get_variable('ENUM');
  713. *
  714. * @param $exten
  715. * @return array, see evaluate for return information.
  716. */
  717. function exec_enumlookup($exten)
  718. {
  719. return $this->exec('EnumLookup', $exten);
  720. }
  721. /**
  722. * Dial.
  723. *
  724. * Dial takes input from ${VXML_URL} to send XML Url to Cisco 7960
  725. * Dial takes input from ${ALERT_INFO} to set ring cadence for Cisco phones
  726. * Dial returns ${CAUSECODE}: If the dial failed, this is the errormessage.
  727. * Dial returns ${DIALSTATUS}: Text code returning status of last dial attempt.
  728. *
  729. * @link http://www.voip-info.org/wiki-Asterisk+cmd+Dial
  730. * @param string $type
  731. * @param string $identifier
  732. * @param integer $timeout
  733. * @param string $options
  734. * @param string $url
  735. * @return array, see evaluate for return information.
  736. */
  737. function exec_dial($type, $identifier, $timeout=NULL, $options=NULL, $url=NULL)
  738. {
  739. return $this->exec('Dial', trim("$type/$identifier|$timeout|$options|$url", '|'));
  740. }
  741. /**
  742. * Goto.
  743. *
  744. * This function takes three arguments: context,extension, and priority, but the leading arguments
  745. * are optional, not the trailing arguments. Thuse goto($z) sets the priority to $z.
  746. *
  747. * @param string $a
  748. * @param string $b;
  749. * @param string $c;
  750. * @return array, see evaluate for return information.
  751. */
  752. function exec_goto($a, $b=NULL, $c=NULL)
  753. {
  754. return $this->exec('Goto', trim("$a|$b|$c", '|'));
  755. }
  756. // *********************************************************************************************************
  757. // ** FAST PASSING **
  758. // *********************************************************************************************************
  759. /**
  760. * Say the given digit string, returning early if any of the given DTMF escape digits are received on the channel.
  761. * Return early if $buffer is adequate for request.
  762. *
  763. * @link http://www.voip-info.org/wiki-say+digits
  764. * @param string $buffer
  765. * @param integer $digits
  766. * @param string $escape_digits
  767. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  768. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  769. */
  770. function fastpass_say_digits(&$buffer, $digits, $escape_digits='')
  771. {
  772. $proceed = false;
  773. if($escape_digits != '' && $buffer != '')
  774. {
  775. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  776. $proceed = true;
  777. }
  778. if($buffer == '' || $proceed)
  779. {
  780. $res = $this->say_digits($digits, $escape_digits);
  781. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  782. $buffer .= chr($res['result']);
  783. return $res;
  784. }
  785. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  786. }
  787. /**
  788. * Say the given number, returning early if any of the given DTMF escape digits are received on the channel.
  789. * Return early if $buffer is adequate for request.
  790. *
  791. * @link http://www.voip-info.org/wiki-say+number
  792. * @param string $buffer
  793. * @param integer $number
  794. * @param string $escape_digits
  795. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  796. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  797. */
  798. function fastpass_say_number(&$buffer, $number, $escape_digits='')
  799. {
  800. $proceed = false;
  801. if($escape_digits != '' && $buffer != '')
  802. {
  803. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  804. $proceed = true;
  805. }
  806. if($buffer == '' || $proceed)
  807. {
  808. $res = $this->say_number($number, $escape_digits);
  809. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  810. $buffer .= chr($res['result']);
  811. return $res;
  812. }
  813. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  814. }
  815. /**
  816. * Say the given character string, returning early if any of the given DTMF escape digits are received on the channel.
  817. * Return early if $buffer is adequate for request.
  818. *
  819. * @link http://www.voip-info.org/wiki-say+phonetic
  820. * @param string $buffer
  821. * @param string $text
  822. * @param string $escape_digits
  823. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  824. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  825. */
  826. function fastpass_say_phonetic(&$buffer, $text, $escape_digits='')
  827. {
  828. $proceed = false;
  829. if($escape_digits != '' && $buffer != '')
  830. {
  831. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  832. $proceed = true;
  833. }
  834. if($buffer == '' || $proceed)
  835. {
  836. $res = $this->say_phonetic($text, $escape_digits);
  837. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  838. $buffer .= chr($res['result']);
  839. return $res;
  840. }
  841. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  842. }
  843. /**
  844. * Say a given time, returning early if any of the given DTMF escape digits are received on the channel.
  845. * Return early if $buffer is adequate for request.
  846. *
  847. * @link http://www.voip-info.org/wiki-say+time
  848. * @param string $buffer
  849. * @param integer $time number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
  850. * @param string $escape_digits
  851. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  852. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  853. */
  854. function fastpass_say_time(&$buffer, $time=NULL, $escape_digits='')
  855. {
  856. $proceed = false;
  857. if($escape_digits != '' && $buffer != '')
  858. {
  859. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  860. $proceed = true;
  861. }
  862. if($buffer == '' || $proceed)
  863. {
  864. $res = $this->say_time($time, $escape_digits);
  865. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  866. $buffer .= chr($res['result']);
  867. return $res;
  868. }
  869. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  870. }
  871. /**
  872. * Play the given audio file, allowing playback to be interrupted by a DTMF digit. This command is similar to the GET DATA
  873. * command but this command returns after the first DTMF digit has been pressed while GET DATA can accumulated any number of
  874. * digits before returning.
  875. * Return early if $buffer is adequate for request.
  876. *
  877. * @link http://www.voip-info.org/wiki-stream+file
  878. * @param string $buffer
  879. * @param string $filename without extension, often in /var/lib/asterisk/sounds
  880. * @param string $escape_digits
  881. * @param integer $offset
  882. * @return array, see evaluate for return information. ['result'] is -1 on hangup or error, 0 if playback completes with no
  883. * digit received, otherwise a decimal value of the DTMF tone. Use chr() to convert to ASCII.
  884. */
  885. function fastpass_stream_file(&$buffer, $filename, $escape_digits='', $offset=0)
  886. {
  887. $proceed = false;
  888. if($escape_digits != '' && $buffer != '')
  889. {
  890. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  891. $proceed = true;
  892. }
  893. if($buffer == '' || $proceed)
  894. {
  895. $res = $this->stream_file($filename, $escape_digits, $offset);
  896. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  897. $buffer .= chr($res['result']);
  898. return $res;
  899. }
  900. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  901. }
  902. /**
  903. * Use festival to read text.
  904. * Return early if $buffer is adequate for request.
  905. *
  906. * @link http://www.cstr.ed.ac.uk/projects/festival/
  907. * @param string $buffer
  908. * @param string $text
  909. * @param string $escape_digits
  910. * @param integer $frequency
  911. * @return array, see evaluate for return information.
  912. */
  913. function fastpass_text2wav(&$buffer, $text, $escape_digits='', $frequency=8000)
  914. {
  915. $proceed = false;
  916. if($escape_digits != '' && $buffer != '')
  917. {
  918. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  919. $proceed = true;
  920. }
  921. if($buffer == '' || $proceed)
  922. {
  923. $res = $this->text2wav($text, $escape_digits, $frequency);
  924. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  925. $buffer .= chr($res['result']);
  926. return $res;
  927. }
  928. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  929. }
  930. /**
  931. * Use Cepstral Swift to read text.
  932. * Return early if $buffer is adequate for request.
  933. *
  934. * @link http://www.cepstral.com/
  935. * @param string $buffer
  936. * @param string $text
  937. * @param string $escape_digits
  938. * @param integer $frequency
  939. * @return array, see evaluate for return information.
  940. */
  941. function fastpass_swift(&$buffer, $text, $escape_digits='', $frequency=8000, $voice=NULL)
  942. {
  943. $proceed = false;
  944. if($escape_digits != '' && $buffer != '')
  945. {
  946. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  947. $proceed = true;
  948. }
  949. if($buffer == '' || $proceed)
  950. {
  951. $res = $this->swift($text, $escape_digits, $frequency, $voice);
  952. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  953. $buffer .= chr($res['result']);
  954. return $res;
  955. }
  956. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}), 'endpos'=>0);
  957. }
  958. /**
  959. * Say Puncutation in a string.
  960. * Return early if $buffer is adequate for request.
  961. *
  962. * @param string $buffer
  963. * @param string $text
  964. * @param string $escape_digits
  965. * @param integer $frequency
  966. * @return array, see evaluate for return information.
  967. */
  968. function fastpass_say_punctuation(&$buffer, $text, $escape_digits='', $frequency=8000)
  969. {
  970. $proceed = false;
  971. if($escape_digits != '' && $buffer != '')
  972. {
  973. if(!strpos(chr(255) . $escape_digits, $buffer{strlen($buffer)-1}))
  974. $proceed = true;
  975. }
  976. if($buffer == '' || $proceed)
  977. {
  978. $res = $this->say_punctuation($text, $escape_digits, $frequency);
  979. if($res['code'] == AGIRES_OK && $res['result'] > 0)
  980. $buffer .= chr($res['result']);
  981. return $res;
  982. }
  983. return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1}));
  984. }
  985. /**
  986. * Plays the given file and receives DTMF data.
  987. * Return early if $buffer is adequate for request.
  988. *
  989. * This is similar to STREAM FILE, but this command can accept and return many DTMF digits,
  990. * while STREAM FILE returns immediately after the first DTMF digit is detected.
  991. *
  992. * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default.
  993. *
  994. * If the user doesn't press any keys when the message plays, there is $timeout milliseconds
  995. * of silence then the command ends.
  996. *
  997. * The user has the opportunity to press a key at any time during the message or the
  998. * post-message silence. If the user presses a key while the message is playing, the
  999. * message stops playing. When the first key is pressed a timer starts counting for
  1000. * $timeout milliseconds. Every time the user presses another key the timer is restarted.
  1001. * The command ends when the counter goes to zero or the maximum number of digits is entered,
  1002. * whichever happens first.
  1003. *
  1004. * If you don't specify a time out then a default timeout of 2000 is used following a pressed
  1005. * digit. If no digits are pressed then 6 seconds of silence follow the message.
  1006. *
  1007. * If you don't specify $max_digits then the user can enter as many digits as they want.
  1008. *
  1009. * Pressing the # key has the same effect as the timer running out: the command ends and
  1010. * any previously keyed digits are returned. A side effect of this is that there is no
  1011. * way to read a # key using this command.
  1012. *
  1013. * @link http://www.voip-info.org/wiki-get+data
  1014. * @param string $buffer
  1015. * @param string $filename file to play. Do not include file extension.
  1016. * @param integer $timeout milliseconds
  1017. * @param integer $max_digits
  1018. * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present.
  1019. *
  1020. * This differs from other commands with return DTMF as numbers representing ASCII characters.
  1021. */
  1022. function fastpass_get_data(&$buffer, $filename, $timeout=NULL, $max_digits=NULL)
  1023. {
  1024. if(is_null($max_digits) || strlen($buffer) < $max_digits)
  1025. {
  1026. if($buffer == '')
  1027. {
  1028. $res = $this->get_data($filename, $timeout, $max_digits);
  1029. if($res['code'] == AGIRES_OK)
  1030. $buffer .= $res['result'];
  1031. return $res;
  1032. }
  1033. else
  1034. {
  1035. while(is_null($max_digits) || strlen($buffer) < $max_digits)
  1036. {
  1037. $res = $this->wait_for_digit();
  1038. if($res['code'] != AGIRES_OK) return $res;
  1039. if($res['result'] == ord('#')) break;
  1040. $buffer .= chr($res['result']);
  1041. }
  1042. }
  1043. }
  1044. return array('code'=>AGIRES_OK, 'result'=>$buffer);
  1045. }
  1046. // *********************************************************************************************************
  1047. // ** DERIVED **
  1048. // *********************************************************************************************************
  1049. /**
  1050. * Menu.
  1051. *
  1052. * This function presents the user with a menu and reads the response
  1053. *
  1054. * @param array $choices has the following structure:
  1055. * array('1'=>'*Press 1 for this', // festival reads if prompt starts with *
  1056. * '2'=>'some-gsm-without-extension',
  1057. * '*'=>'*Press star for help');
  1058. * @return mixed key pressed on sucess, -1 on failure
  1059. */
  1060. function menu($choices, $timeout=2000)
  1061. {
  1062. $keys = join('', array_keys($choices));
  1063. $choice = NULL;
  1064. while(is_null($choice))
  1065. {
  1066. foreach($choices as $prompt)
  1067. {
  1068. if($prompt{0} == '*')
  1069. $ret = $this->text2wav(substr($prompt, 1), $keys);
  1070. else
  1071. $ret = $this->stream_file($prompt, $keys);
  1072. if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
  1073. {
  1074. $choice = -1;
  1075. break;
  1076. }
  1077. if($ret['result'] != 0)
  1078. {
  1079. $choice = chr($ret['result']);
  1080. break;
  1081. }
  1082. }
  1083. if(is_null($choice))
  1084. {
  1085. $ret = $this->get_data('beep', $timeout, 1);
  1086. if($ret['code'] != AGIRES_OK || $ret['result'] == -1)
  1087. $choice = -1;
  1088. elseif($ret['result'] != '' && strpos(' '.$keys, $ret['result']))
  1089. $choice = $ret['result'];
  1090. }
  1091. }
  1092. return $choice;
  1093. }
  1094. /**
  1095. * Goto - Set context, extension and priority.
  1096. *
  1097. * @param string $context
  1098. * @param string $extension
  1099. * @param string $priority
  1100. */
  1101. function agigoto($context, $extension='s', $priority=1)
  1102. {
  1103. $this->set_context($context);
  1104. $this->set_extension($extension);
  1105. $this->set_priority($priority);
  1106. }
  1107. /**
  1108. * Parse caller id.
  1109. *
  1110. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  1111. * @example examples/input.php Get text input from the user and say it back
  1112. *
  1113. * "name" <proto:user@server:port>
  1114. *
  1115. * @param string $callerid
  1116. * @return array('Name'=>$name, 'Number'=>$number)
  1117. */
  1118. function parse_callerid($callerid=NULL)
  1119. {
  1120. if(is_null($callerid))
  1121. $callerid = $this->request['agi_callerid'];
  1122. $ret = array('name'=>'', 'protocol'=>'', 'username'=>'', 'host'=>'', 'port'=>'');
  1123. $callerid = trim($callerid);
  1124. if($callerid{0} == '"' || $callerid{0} == "'")
  1125. {
  1126. $d = $callerid{0};
  1127. $callerid = explode($d, substr($callerid, 1));
  1128. $ret['name'] = array_shift($callerid);
  1129. $callerid = join($d, $callerid);
  1130. }
  1131. $callerid = explode('@', trim($callerid, '<> '));
  1132. $username = explode(':', array_shift($callerid));
  1133. if(count($username) == 1)
  1134. $ret['username'] = $username[0];
  1135. else
  1136. {
  1137. $ret['protocol'] = array_shift($username);
  1138. $ret['username'] = join(':', $username);
  1139. }
  1140. $callerid = join('@', $callerid);
  1141. $host = explode(':', $callerid);
  1142. if(count($host) == 1)
  1143. $ret['host'] = $host[0];
  1144. else
  1145. {
  1146. $ret['host'] = array_shift($host);
  1147. $ret['port'] = join(':', $host);
  1148. }
  1149. return $ret;
  1150. }
  1151. /**
  1152. * Use festival to read text.
  1153. *
  1154. * @example examples/dtmf.php Get DTMF tones from the user and say the digits
  1155. * @example examples/input.php Get text input from the user and say it back
  1156. * @example examples/ping.php Ping an IP address
  1157. *
  1158. * @link http://www.cstr.ed.ac.uk/projects/festival/
  1159. * @param string $text
  1160. * @param string $escape_digits
  1161. * @param integer $frequency
  1162. * @return array, see evaluate for return information.
  1163. */
  1164. function text2wav($text, $escape_digits='', $frequency=8000)
  1165. {
  1166. $text = trim($text);
  1167. if($text == '') return true;
  1168. $hash = md5($text);
  1169. $fname = $this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR;
  1170. $fname .= 'text2wav_' . $hash;
  1171. // create wave file
  1172. if(!file_exists("$fname.wav"))
  1173. {
  1174. // write text file
  1175. if(!file_exists("$fname.txt"))
  1176. {
  1177. $fp = fopen("$fname.txt", 'w');
  1178. fputs($fp, $text);
  1179. fclose($fp);
  1180. }
  1181. shell_exec("{$this->config['festival']['text2wave']} -F $frequency -o $fname.wav $fname.txt");
  1182. }
  1183. else
  1184. {
  1185. touch("$fname.txt");
  1186. touch("$fname.wav");
  1187. }
  1188. // stream it
  1189. $ret = $this->stream_file($fname, $escape_digits);
  1190. // clean up old files
  1191. $delete = time() - 2592000; // 1 month
  1192. foreach(glob($this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR . 'text2wav_*') as $file)
  1193. if(filemtime($file) < $delete)
  1194. unlink($file);
  1195. return $ret;
  1196. }
  1197. /**
  1198. * Use Cepstral Swift to read text.
  1199. *
  1200. * @link http://www.cepstral.com/
  1201. * @param string $text
  1202. * @param string $escape_digits
  1203. * @param integer $frequency
  1204. * @return array, see evaluate for return information.
  1205. */
  1206. function swift($text, $escape_digits='', $frequency=8000, $voice=NULL)
  1207. {
  1208. if(!is_null($voice))
  1209. $voice = "-n $voice";
  1210. elseif(isset($this->config['cepstral']['voice']))
  1211. $voice = "-n {$this->config['cepstral']['voice']}";
  1212. $text = trim($text);
  1213. if($text == '') return true;
  1214. $hash = md5($text);
  1215. $fname = $this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR;
  1216. $fname .= 'swift_' . $hash;
  1217. // create wave file
  1218. if(!file_exists("$fname.wav"))
  1219. {
  1220. // write text file
  1221. if(!file_exists("$fname.txt"))
  1222. {
  1223. $fp = fopen("$fname.txt", 'w');
  1224. fputs($fp, $text);
  1225. fclose($fp);
  1226. }
  1227. shell_exec("{$this->config['cepstral']['swift']} -p audio/channels=1,audio/sampling-rate=$frequency $voice -o $fname.wav -f $fname.txt");
  1228. }
  1229. // stream it
  1230. $ret = $this->stream_file($fname, $escape_digits);
  1231. // clean up old files
  1232. $delete = time() - 2592000; // 1 month
  1233. foreach(glob($this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR . 'swift_*') as $file)
  1234. if(filemtime($file) < $delete)
  1235. unlink($file);
  1236. return $ret;

Large files files are truncated, but you can click here to view the full file