PIONEERS gTTS for Debian, Rocky, and Ubuntu

smccloud

Member
Joined
Jun 17, 2013
Messages
131
Reaction score
14
I've been asked if it's possible to have a recording in an IVR update daily with the current date and the price for the three main items people request pricing on for my brother-in-law's recycling business. Ideally, the system would automatically generate this and not have to be created by someone every morning. Is this possible? I do have the ability to store the prices in a database that can be updated using a simple PHP site or C# app to handle that part. I could even have the C# app automate create the IVR recording, I'm not sure if an IVR recording can be automatically swapped out like that though.
 
If you can generate the audio file with the daily pricing message you are almost there.

You start by making a recording on your PBX (it doesn't matter what is recorded, it will be overwritten daily).
You attach that recording to your inbound route as an announcement (or IVR if you want the user to press a key, etc).

On your workstation/server, wherever you will be preparing the daily audio file, you prepare it with the same name as the one on the PBX. Then at a set time once a day and every day, via the network you upload it using the scp command to the PBX.
Finally on the PBX you reload asterisk to ensure that the new file is taken into account, and for that you use cron.

You could even make a two liner on the PBX and run it under cron so that the PBX pulls in the file from your machine where the audio file is daily made and restarts asterisk.

You need to be careful that the audio file you create is compatible with asterisk's recording format.
(If I recall correctly it's like: .wav file, mono, PCM encoded, 16 bits, 8 KHz sampling rate)
 
Last edited:
Its really easy if you set up a free IBM Watson account and get the API key for text to voice. Ward posted an araticle on Wastson on nerdvittles.com

Here is a script I use to send text from the dial plan to Watson which returns the audio:
Code:
#!/bin/bash
arg1="$1"
curl -X POST -u "apikey:your api key goes here" \
--header "Content-Type: application/json" \
--header "Accept: audio/basic" \
--data "{\"text\":\"$1\"}" \
--output /var/lib/asterisk/sounds/en/custom/temp.ulaw \
"https://api.us-south.text-to-speech.watson.cloud.ibm.com/instances/c9888055-227b-42f4-95fb-3454af9795c5/v1/synthesize?voice=en-US_LisaV3Voice"

In this simple demonstration, I take the incoming caller-id and have it translated to an announcement with Wastson. Here's the code from /etc/asterisk/extensions_cucstom.conf. My Bash script is named "test" and I placed it in /usr/bin. You can set a custom destination to the context.
Code:
[custom-page-callerid]
exten => s,1,Macro(user-callerid,)
exten => s,n,System(/usr/bin/test " ${CALLERID(name)} " )
exten => s,n,Gosub(app-paging,ssetup,1())
exten => s,n,Set(PAGEMODE=PAGE)
exten => s,n,Set(PAGE_MEMBERS=2013-218-220)
exten => s,n,Set(PAGE_CONF_OPTS=duplex)
exten => s,n,Set(ANNOUNCEMENT=custom/temp)
exten => s,n(agi),AGI(page.agi)
exten => s,n,Set(CONFBRIDGE(user,template)=page_user_duplex)
exten => s,n,Set(CONFBRIDGE(user,admin)=yes)
exten => s,n,Set(CONFBRIDGE(user,marked)=yes)
;exten => s,n,Answer
exten => s,n(page),ConfBridge(${PAGE_CONF},,,admin_menu)
exten => s,n,Hangup

This should give you an idea how to take your text and have it send back to a recording. This can probably be modified to work with Googlets but this should give you some ideas. You probably would not need any custom dialplan code if you run it all as a background batch file.

You could run a script once a day to get the product names, price, etc., and store it as a text file. Then put together the phrase and data you want and send it to the bash script which will return that day's recording that you can then access.
 
Last edited:
pip3 install pydub and gtts as needed,
call this with script with argv[1] as your "quoted" message, lang= and tld= as per documentation

Code:
#!/usr/bin/env python3
import sys
import os
from pydub import AudioSegment
from gtts import gTTS
short_silence = AudioSegment.silent(duration=500)
short_silence = short_silence.set_frame_rate(8000)
tts = gTTS(sys.argv[1], lang='en', tld='com')
tts.save('tmp.mp3')
sound = AudioSegment.from_mp3("tmp.mp3")
sound = sound.set_frame_rate(8000)
final = short_silence + sound
final.export("/var/lib/asterisk/sounds/en/custom/ivr-1.wav", format='wav')
os.chown("/var/lib/asterisk/sounds/en/custom/ivr-1.wav", 1000, 1000)                                                  
os.remove("tmp.mp3")

[\code]

if the asterisk user's ID is not 1000 edit script to suit.
 
Last edited:
I went the C# route using Renci.SshNet for communication with the PBX to run commands (generate the wav file using googletts-cli.pl, Newtonsoft.Json to store the last known prices for automatic runs. And since it works for me, a StringBuilder to build the IVR text. It may not be the most efficient way, but it does work. I have the GUI portion done, next step it split functions out of the GUI into their own classes so I can call them from a CLI app to handle the automatic updates.
 
I think you're making this too hard. If the platform is Incredible PBX for Debian or Rocky, all of this logic already is built into the sample ODBC scripts using PicoTTS. Dial 222 on either platform and enter 12345 for the employee number for a demo. Then take a look at the code in /etc/asterisk/odbc.conf which can be modified easily. All you really need is a little bash script to stuff the items and prices into a MySQL table each day, and everything else would be automatic.

If I were your brother-in-law, I'd never stake my business on a Google app, especially TTS. They change, break, or delete apps without any regard for the people that use them. Anybody remember Google Voice, Google Talk, Google Health, G Suite (free edition), Google Reader, Knol, and on and on?
 
Last edited:
Compare the quality of

gtts-cli "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')"| play -t mp3 -

and

pico2wave --wave=w.wav "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')";play w.wav


Use your preferred method given it is 2022 ;-)

Other benefits, no API-KEY or account needed, more languages and intonations built in, and no clipping of the first few phonemes.
 
I think you're making this too hard. If the platform is Incredible PBX for Debian or Rocky, all of this logic already is built into the sample ODBC scripts using PicoTTS. Dial 222 on either platform and enter 12345 for the employee number for a demo. Then take a look at the code in /etc/asterisk/odbc.conf which can be modified easily. All you really need is a little bash script to stuff the items and prices into a MySQL table each day, and everything else would be automatic.

If I were your brother-in-law, I'd never stake my business on a Google app, especially TTS. They change, break, or delete apps without any regard for the people that use them. Anybody remember Google Voice, Google Talk, Google Health, G Suite (free edition), Google Reader, Knol, and on and on?
I may be making it harder on myself, but easier on them to use. I’d rather it take me a day or three to code and test but is much easier for them to use.
 
Compare the quality of

gtts-cli "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')"| play -t mp3 -

and

pico2wave --wave=w.wav "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')";play w.wav


Use your preferred method given it is 2022 ;-)

Other benefits, no API-KEY or account needed, more languages and intonations built in, and no clipping of the first few phonemes.
I will have to try that this weekend. Thankfully I have a L2TP VPN from home.
 
I will have to try that this weekend. Thankfully I have a L2TP VPN from home.
I would comment that

googletts-cli.pl is 7 years old and basically abandoned.
Newtonsoft.Json is implemented with ' import json' in python
StringBuilder is just a bunch of concatenations in python, get the date string with strftime() extract you current data with a python 'wrapper ' easily available for mysql, mongodb sqlite3 or most anything. insert any additional text to make it coherent.

If you are windoze bound, you can do all this on your m$ host with python3 and gtts and pydub before scp'ing it over to your current ${IVR_MSG} for your desired 'ivr-n', if you do it that way, make sure you are using the asterisk users account with ssh
 
Last edited:
I guess my position is that Asterisk is a well written c++ app of a couple decades ago , inheriting a major component from a previously written 'comedian mail' it's database was BerkleyDB but long ago rewritten to sqlite3 (a good thing)

FreePBX and it's derivatives all hang off amportal that was a very good effort to write the asterisk dialplan prettily using php, mysql and a webserver (note-bene I don't say which 'webserver' )

So Asterisk is very efficient with external apps provisioning resources in /etc/asterisk/voicemail.conf and consulting the astdb sqlite3 for anything 'dynamic'.

( note also that astdb is thread-safe but not multi-user safe, you should wrap any such sqlite3 queries including 'reads' around the 'asterisk database' interface if asterisk is running, but that's another story)

The collision is that FreePBX is basically restricted to using the same old PHP/MYSQL framework to rewrite /etc/asterisk/*.conf, astdb and voicemail.conf. So is by nature 'asynchronous' and needs a fwconsole reload to plant it's intentions.

Here the OP wants a simple audio file updated per diem, this is a simple job, the ivr-n plays whatever is at ${IVR_MSG} in that context , if that file is of the correct format and with the correct ownership, then 'NFP' neither Asterisk nor FreePBX is in play, the caller will just hear that content.

So the job here is to TTS the sum of any garnered internal data and syntactically correct grammar into a well formed 'wav' file.

There are many TTS solutions, some cost money and are not easily scripted, some are 'free' but sound like sh*t , some need API-KEYS and are 'rate-limited' or 'cost-limited' and these are the ones (not just gcloud ! ) that have constantly mutated and need regular fixing .

The more byzantine the solution is, the more likely it will break.

Here I use Python and an imported module that has been rock-solid for 7 years with none of the above impediments , maybe not quite as fast as golang but easy to understand and implement/debug and almost 'infinitely' extensible . Also ideal for getting commonly available json formatted data from any number of API's be that weather, commodity prices, zip codes, verify phone numbers, possibly ban ASN's or IP geolocation in fail2ban for those still using UDP/5060 ;-) . In this case with 14 lines of 'code'.

JM2CWAE (and I would have very similar arguments for STT)

If @smccloud cares to share the nature of his data source, I will write that for him in python also ;-)
 
Last edited:
Compare the quality of

gtts-cli "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')"| play -t mp3 -

and

pico2wave --wave=w.wav "$(curl -sf "https://api.weather.gov/gridpoints/LOX/142,57/forecast"|jq -r '.properties.periods[0].detailedForecast')";play w.wav


Use your preferred method given it is 2022 ;-)

Other benefits, no API-KEY or account needed, more languages and intonations built in, and no clipping of the first few phonemes.
Just tried this, but how do you get an 8000Hz file out of pico2wave?
 
Either will work, sox is 'lighter weight' than ffmpeg cos it only needs audio libraries loaded,

pydub is quicker with gtts if you want to go that way and do a lot of TTS
 
Last edited:
If you'd like to try out gTTS with Incredible PBX on either the Debian or Ubuntu platforms, here are the steps to use it with Weather Reports by ZIP Code (947) and News Headlines (951). It's also included in the latest Oracle Cloud build.
Code:
cd /var/lib/asterisk/agi-bin
apt-get -y install pip
apt-get -y install jq
apt-get -y install libsox-fmt-all
pip install gTTS
wget http://incrediblepbx.com/gtts.tar.gz
tar zxvf gtts.tar.gz
rm -f gtts.tar.gz
./install-gtts-dialplan.sh
 

Members online

No members online now.

Forum statistics

Threads
26,751
Messages
174,798
Members
20,313
Latest member
bml5631
Get 3CX - Absolutely Free!

Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.
Back
Top