Using VoiceRSS services in Asterisk

For those interested in, I developed a small AGI to allow reading and reproducing text strings on Asterisk.
The process is based on free services supplied by VoiceRSS (http://http://www.voicerss.org/).
VoiceRSS also provides payment services in case the number of daily requests exceeds 300.
The code developed is php, but VoiceRSS also supply libraries for perl, python and many other languages.
To be able to use the services, users must register to get a free access key.
This AGI can be called inside a custom destination like the following

[test-destination]
exten => s,1,Answer()
exten => s,n,AGI(voice_tts.php,,“Stringa di testo che contiene il vostro annuncio”,it-it)
exten => s,n,Macro(hangupcall)

Following is the AGI code:

#!/usr/bin/php -q
<?php

// -----------------------------------------------------------------
// Script that uses VoiceRSS Translate for text to speech synthesis.
//
// Copyright (C) 2017 Paolo Scaglione (p.scaglione@formatgroup.it)
//
// This program is free software, distributed under the terms of
// the GNU General Public License Version 2.
// ------------------------------------------------------------------
// 22.05.2017
// V 0.1.0
// ------------------------------------------------------------------

include_once ("/etc/freepbx.conf");
define("AGIBIN_DIR", "/var/lib/asterisk/agi-bin");
define("AMPORTAL_CONF", "/etc/amportal.conf");
include(AGIBIN_DIR."/phpagi.php");
error_reporting(0);

// --------------------------------------------------------------------------------------------------------------------------------------------------
require_once('voicerss_tts.php'); // supplied by VoiceRSS.org
//$url = "http://api.voicerss.org/"; 
// --- Original VoiceRSS API Parameters -------------------------------------------------------------------------------------------------------------
//
//key	The API key (mandatory)
//src	The textual content for converting to speech (length limited by 100KB) (mandatory).
//hl		The textual content language. Allows values: see Languages. (mandatory)
//r		The speech rate (speed). Allows values: from -10 (slowest speed) up to 10 (fastest speed). Default value: 0 (normal speed). (optional)
//c		The speech audio codec. Allows values: see Audio Codecs. Default value: MP3. (optional)
//f		The speech audio formats. Allows values: see Audio Formats. Default value: 8khz_8bit_mono. (optional)
//ssml	The SSML textual content format. Allows values: true and false. Default value: false. (optional)
//b64	Defines output as a Base64 string format (for an internet browser playing). Allows values: true and false. Default value: false. (optional)
// --------------------------------------------------------------------------------------------------------------------------------------------------
$key    = '';
$text;									// String to be spoken
$lang	= "en-us";						// language
$speed	= 0; 							// (-10 slowest, 0 normal, 10 fastest)
$format = '41khz_8bit_mono';
$codec  = 'mp3';						// mp3, wav, aac, ogg, caf
$ssml	= 0;
$b64	= 1;
$tmpdir	= '/tmp';						// temp dir

// Create new AGI instance
//
$agi = new AGI();
$v1 = 1;
@$agi->verbose("Call VoiceTTS [START]",$vl);


// Store AGI parameters
// -----------------------------------------------------------------
// Service Key (mandatory)
// Text to be spoken (mandatory)
// Language (optional) - default US English
// Speed (optional) - default 0 (normal)

// -----------------------------------------------------------------
if (isset($argv[1])) {$key   = $argv[1];}
else {
	@$agi->verbose("No service Key supplied.",$vl);
	agiexit(50);
}
if (isset($argv[2])) {$text = $argv[2];}
else {
	@$agi->verbose("No Text supplied.",$vl);
	agiexit(50);
}
if (isset($argv[2])) {$lang  = $argv[3];}
if (isset($argv[3])) {$speed = $argv[4];}

//@$agi->verbose("AGI params: ".$text." ".$lang." ".$speed." ".$key,$v1);

$settings = array(
    'key' => $key,
    'hl' => $lang,
    'src' => $text,
    'r' => $speed,
    'c' => $codec,
    'f' => $format,
    'ssml' => $ssml,
    'b64' => $b64
);

// new VoiceRRS object instance
$tts = new VoiceRSS;
$voice = $tts->speech($settings);

if ($voice['error']) {
	@$agi->verbose($voice['error'],$vl);
} else {
	// Create audio file
	$tempFile = tempnam($tmpdir, 'tmp_msg_');
	$fh = fopen($tempFile, "w"); 
    fwrite($fh, $voice['response']);
    fclose($fh);
	// Play audio and delete from tempdir
	$agi->exec('MP3Player',"$tempFile");
	unlink($tempFile);
}

@$agi->verbose("Call VoiceTTS [END]",$vl);

exit(0);

// AGI Exit function
//
function agiexit($prio) {
        global $agi;
        $agi->set_priority($prio);
        exit(0);
}

?>
4 Likes

@paolo: can you please translate your post in English so all our members can read it?

1 Like

done.

2 Likes

Thank you!

I just formatted your contribute as code :wink:

Thanks Paolo, I guess it could helpful for our PBX guys: @clinton @fred @adam @chrisg @ghost @petralemoisson @edi

Thank you @paolo for the translation.

May I voice a small concern: This seems to be a script for an external service. By providing only this service the important option of choice reduces to use the script or not use the script.
The concept of choice is one of the main pillars of opensource. What I would prefer in such a case is either a more generic script that can be used with several services. Even better would be if you could use the functionality of the script for your own hosted services.
What would it take to adapt to such a concept?

Nice work Paolo!

change this

in
#!/usr/bin/env php

to use php 5.6 to execute agi and avoid php error. https://github.com/NethServer/dev/issues/5499