#!/usr/bin/php -q get_full_variable('${CHANNEL(audionativeformat)}'); $nformat = $f['data']; $format = array( "ext" => "sln", "rate" => "8000" ); //amazing work my friend: https://github.com/stevenmirabito/asterisk-picotts/blob/master/picotts.agi#L251 switch(true) { case preg_match('/(silk|sln)12/',$nformat): $format = array( "ext" => "sln12", "rate" => "12000" ); break; case preg_match('/(speex|slin|silk)16|g722|siren7/',$nformat): $format = array( "ext" => "sln16", "rate" => "16000" ); break; case preg_match('/(speex|slin|celt)32|siren14/',$nformat): $format = array( "ext" => "sln32", "rate" => "32000" ); break; case preg_match('/(celt|slin)44/',$nformat): $format = array( "ext" => "sln44", "rate" => "44000" ); break; case preg_match('/(celt|slin)48/',$nformat): $format = array( "ext" => "sln48", "rate" => "48000" ); break; default; $format = array( "ext" => "sln", "rate" => "8000" ); break; } if (!isset($text)) { return 0; } if ( $retval != 0 ) { debug("ERROR: TTS engine binary not found.", 1); return $retval; } $soundsdir = $config["ASTVARLIBDIR"]."/sounds/tts"; if( !is_dir($soundsdir) ) mkdir($soundsdir, 0775); $wavefile = $soundsdir."/$engine-tts-$hash.".$format['ext']; $tmpwavefile = $soundsdir."/$engine-tts-temp-$hash.wav"; debug("Generated WAV file: $wavefile", 3); $textfile = $soundsdir."/$engine-tts-$hash.txt"; debug("TXT file: $textfile", 3); if ( !file_exists($wavefile) ) { debug("Text to speech wave file doesnt exist, lets create it.", 1); if ( false === ($fh = fopen($textfile, "w")) ) { debug("ERROR: Cannot open the file: $textfile", 1); return 1; } if ( false === fwrite($fh, $text) ) { debug("ERROR: Cannot write to file: $textfile", 1); return 1; } fclose($fh); debug("Executing $engine", 1); switch ($engine) { case 'text2wave': exec($enginebin." -f ".$format['rate']." -o $tmpwavefile $textfile"); break; case 'flite': exec($enginebin." -f $textfile -o $tmpwavefile"); break; case 'swift': exec($enginebin." -p audio/channels=1,audio/sampling-rate=".$format['rate']." -o $tmpwavefile -f $textfile"); break; case 'pico': exec($enginebin." -o $tmpwavefile ".escapeshellarg(file_get_contents($textfile))); break; case 'polly': exec($enginebin." /opt/aws-nodejs/polly.js --mp3=/var/lib/asterisk/sounds/tts/$engine-tts-$hash.mp3 --text='$text' --wav=/var/lib/asterisk/sounds/tts/$engine-tts-temp-$hash"); break; default: debug("$engine is not a valid engine!", 1); break; } } if(file_exists($tmpwavefile)) { exec("sox $tmpwavefile -q -r ".$format['rate']." -t raw $wavefile"); unlink($tmpwavefile); } if(file_exists($wavefile)) { // Adding a wait because the first time the wave file is generated, it was not played $AGI->wait_for_digit(1000); debug("Streaming the generated wave.", 1); $AGI->stream_file("tts/".basename($wavefile,".".$format['ext']),'#'); } else { debug("File was not created!", 1); } debug("TTS AGI end", 1); function parse_amportal_conf($filename) { $file = file($filename); $matches = array(); $matchpattern = '/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/'; foreach ($file as $line) { if (preg_match($matchpattern, $line, $matches)) { $conf[ $matches[1] ] = $matches[2]; } } return $conf; } function debug($string, $level=3) { global $AGI; $AGI->verbose($string, $level); }