I set up Pico TTS on my Raspberry Pi running FreePBX 15.0.23.17 / Asterisk 16.21.1 by compiling it from the Debian sources:
apt-get source libttspico-utils
apt install autoconf libtool help2man libpopt-dev debhelper
cd svox-1.0+git20130326/
dpkg-buildpackage -rfakeroot -us -uc
dpkg -i libttspico*.deb
I also installed picospeaker
from Files · master · Kyle / picospeaker · GitLab, as this thread notes is required.
I created a TTS Engine definition with Path set to /usr/bin/picospeaker
and type set to pico
, and some TTS entries that use that engine. For testing, I set up a custom application that plays a TTS entry "Example Text"
when I dial *7777
.
When I dial the extension, the system immediately hangs up without playing any audio.
Checking the logs, I see this:
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: TTS AGI Started
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: Generated WAV file: /var/lib/asterisk/sounds/tts/pico-tts-044710b4744c63f94697537783278282.sln
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: TXT file: /var/lib/asterisk/sounds/tts/pico-tts-044710b4744c63f94697537783278282.txt
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: Text to speech wave file doesnt exist, lets create it.
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: Executing pico
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: File was not created!
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: TTS AGI end
res_agi.c: <PJSIP/2004-000000eb>AGI Script agi://127.0.0.1/propolys-tts.agi completed, returning 0
I looked in the output directory and confirmed that there is no output file there.
I modified my /var/lib/asterisk/agi-bin/propolys-tts.agi
script to print additional debug output. Specifically, I have it printing the exit code of the picospeaker
invocation, as well as the complete command that it tried to execute. I also have it redirect stdout
to stderr
so I can see if there are errors from picospeaker
.
$output = null;
$returncode = 0;
exec($enginebin." -o $tmpwavefile ".escapeshellarg(file_get_contents($textfile)) . ' 2>&1', $ouput, $returncode);
debug("Ran: $enginebin -o $tmpwavefile ".escapeshellarg(file_get_contents($textfile))." 2>&1 - Output: (code $returncode) '" . implode("; ", $output) . "'");
Here is an example of the log output:
res_agi.c: agi://127.0.0.1/propolys-tts.agi,"Example Text",pico,/usr/bin/picospeaker: Ran: /usr/bin/picospeaker -o /var/lib/asterisk/sounds/tts/pico-tts-temp-044710b4744c63f94697537783278282.wav 'Example Text' 2>&1 - Output: (code 1) ''
As you can see, picospeaker
exits with an error code 1
.
The problem is that if I copy the command text from the log and run it myself on the command line, it works. (I even used sudo
to run it as the asterisk
user instead of as root
):
sudo -u asterisk /usr/bin/picospeaker -o /var/lib/asterisk/sounds/tts/pico-tts-temp-044710b4744c63f94697537783278282.wav 'Example Text' 2>&1
When I run this command, the temp output file is created successfully, and the exit code is 0
as expected. When I next dial *7777
from my phone, the system still fails to run picospeaker
but it finds the temp output file from my manual run and uses that file (processed through sox
) to generate the spoken output.
Why does the picospeaker
command work when I run it by hand but not when the AGI runs it? How can I fix this?