Archiv

Archiv für die Kategorie ‘Linux’

Cepstral TTS Voiceprompt Script für Asterisk

26. Mai 2011 Keine Kommentare

Cepstral bietet eine der wenigen brauchbaren TTS-Engines für Linux an. Das folgende Script bietet eine einfache Möglichkeit im Asterisk Diaplan Voiceprompts on-demand zu erstellen. Um dieses möglichst ressourcenschonend zu realisieren, wird jeder angeforderte Text nur einmal erstellt und entsprechend via einem Hash gespeichert. Bei jedem Aufruf nach einem bereits bestehenden identischem Hashtag gesucht.

Der Aufruf in der Asterisk extentions.conf erfolgt nach folgendem Syntax:

exten => _X.,n,AGI(tts-play.pl,"Hallo Welt!")

Das Script muß sich in diesem Fall im agi-bin Verzeichnis der Asterisk Installation befinden. Außerdem sollten die Pfade in den ersten Zeilen des Programms angepasst werden.

tts-play.pl

#!/usr/bin/perl
use XML::Simple;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
use Asterisk::AGI;

$SWIFT = "/opt/swift/bin/swift";
$GSMDIR = "/opt/asterisk/var/lib/asterisk/sounds";

if ( $#ARGV < 0 )
{
   print "Wrong syntax!\n";
   print "./tts-play.pl 'text' 'langcode'\n";
   exit;
}

my $text = shift;
my $lang = shift;
my $hash = md5_hex($text);

if ( $lang == "" )
{
   $lang = "de";
}

$AGI = new Asterisk::AGI;

# Check for the existing destination directory.
if (! -e "$GSMDIR" . "/". $lang )
{
   `mkdir -p $GSMDIR/$lang`;
}

# If the file does not exist, fetch it. Otherwise leave everything untouched.
if (! -e "$GSMDIR/". $lang ."/tts-". $hash .".wav" )
{
   `$SWIFT -o $GSMDIR/$lang/tts-$hash.wav -p audio/sampling-rate=8000,audio/channels=1 \"$text\"`;
}

$AGI->exec("PLAYBACK", "$GSMDIR". "/". $lang ."/tts-". $hash)

Hinweis zur Asterisk Konfiguration für Sipgate-Team

23. Mai 2010 Keine Kommentare

Seit langer Zeit hatte ich mal wieder Zeit, mich mit der PBX-Software Asterisk zu beschäftigen. Um mit einem Testsystem starten zu können, fehlte mir jedoch noch ein ordentlicher mit vielen Features ausgestatteter SIP-Zugang. Nach vielen Überlegungen ist meine Wahl auf “Sipgate Team” gefallen. SIP-Trunking, SetCallerID und vieles mehr ist hier möglich. Von daher bin ich sehr optimistisch, was die kommende Umsetzung meiner Ideen in via Asterisk angeht.

Nach dem Kompilieren und Installieren der PBX-Software habe ich mich mit der Konfiguration des SIP-Zugangs auseinandergesetzt. Hier hat sich jedoch ein Fehler in der Dokumentation von Sipgate eingeschlichen. Auf den Supportseiten findet man den Hinweis, dass in der sip.conf von Asterisk die Zugangsdaten wie folgt hinterlegt werden sollen:

Falsch!

register => SIP-ID:SIP-Passwort@sipgate.de/SIP-ID

[sipgate.de]
type=peer
secret=SIP_PASSWORT
insecure=invite
username=SIP-ID
defaultuser=SIP-ID
fromuser=SIP-ID
context=sipgate_in
fromdomain=sipgate.de
host=sipgate.de
outboundproxy=proxy.live.sipgate.de
qualify=yes
disallow=all
allow=alaw
dtmfmode=rfc2833

Mit dieser Konfiguration ist es unmöglich in der Asterisk extenstions.conf eine Extension zu erstellen, in die ein eingehender Anruf laufen soll. Das Problem liegt an der falsch definierten host= Zeile. Der
Asterisk-Server kann so eingehende Anrufe dem entsprechenden Kontext nicht korrekt zuordnen.

Asterisk Fehlermeldung:

Call from '' to extension '123456789' rejected because extension not found.

Wie folgt sieht eine funktionierende Konfiguration aus:

register=SIP-ID@sipgate.de:SIP_PASSWORT@proxy.live.sipgate.de/SIP-ID

[sipgate-team.de]
type=peer
username=SIP-ID
fromuser=SIP-ID
defaultuser=SIP-ID
secret=SIP_PASSWORT
host=proxy.live.sipgate.de
fromdomain=sipgate.de
canreinvite=no
insecure=port,invite
context=in_sipgate-team

Ich habe diese Konfiguration erfolgreich auf einem 1.6er Asterisk-Server am laufen.

Update 25.05.2010
Und wie immer liegt die Lösung in der goldenen Mitte. Mit der obigen Konfiguration werden ankommende Verbindungen zwar dem richtigen Context zugeordnet, abgehende Gespräche werden von Sipgate jedoch mit

handle_response_invite: Received response: "Forbidden" from ...

abgelehnt. Die korrekte Lösung für Sipgate-Team ist die Erstellung eines Eintrags für ausgehende sowie eingehende Gespräche. Das ganze sieht dann so aus:

register=SIP-ID@sipgate.de:SIP-PASS@proxy.live.sipgate.de/SIP-ID

[in_sipgate-team.de]
type=peer
username=SIP-ID
fromuser=SIP-ID
defaultuser=SIP-ID
secret=SIP-PASS
host=proxy.live.sipgate.de
fromdomain=sipgate.de
canreinvite=no
insecure=port,invite
context=in_sipgate-team

[out_sipgate-team.de]
type=peer
username=SIP-ID
fromuser=SIP-ID
defaultuser=SIP-ID
secret=SIP-PASS
host=sipgate.de
fromdomain=sipgate.de
outboundproxy=proxy.live.sipgate.de
canreinvite=no
insecure=port,invite

Eingehende Anrufe landen im Context in_sipgate-team und ausgehende Calls können beispielsweise via

exten => _X.,n,Dial(SIP/${EXTEN}@out_sipgate-team.de)

initiiert werden.

Tags: , ,