Ankündigung

Einklappen
Keine Ankündigung bisher.

Neues Wiregate-Plugin für Sprachausgabe

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [WireGate-Plugin] Neues Wiregate-Plugin für Sprachausgabe

    <hatte das zunächst versehentlich im falschen Bereich gepostet. Jetzt korrekt>

    Hallo zusammen,
    hier mein erster Plugin-Beitrag zum Wiregate:

    Dieses Plugin benötigt Ziffern, Zahlen und Wörter als WAV-Dateien in einem besonderen Verzeichnis. Diese Audiodateien kann man sich bspw in der SVOX-Demo generieren, bzw. ich denke es ist auch kein Problem, wenn ich mein vorhandenes Verzeichnis "mitliefere".

    Mit diesen Voraussetzungen kann das Plugin dann Dinge aufsagen wie "Guten Morgen, es ist Montag elf Uhr fünfundzwanzig" oder "Auf Wiedersehen, Aussentemperatur drei komma fünf Grad" oder "Heutiges Datum Elfter April".

    Die Idee dabei ist, den GA-Namen, so wie er in eibga.conf hinterlegt ist, sowie den DPTSubId-Typen als Basis zu nehmen:

    * Entspricht der GA-Name einem bestimmten Muster, so wird die GA abonniert ("subscribed"). Das zutreffende Muster entscheidet dabei über den ALSA-Ausgabekanal.

    * Explizit abonnierte GAs, die keinem Muster entsprechen, werden im konfigurierten "default"-ALSA-Kanal gesprochen.

    * Der GA-Name selbst (ohne den auf das Kanalmuster passenden Teil) ist der vorzulesende Text.

    * An den Text angehängt wird dann der Datenteil des Telegramms, wobei Kardinalzahlen bei S8/S16 (-32767...+32767), Ordinalzahlen bei U8/U16 (0..65535), Prozentsätze, Temperaturen mit einer Nachkommastelle, spezielle Angaben wie "hoch/runter", "auf/zu" und Datums- sowie Uhrzeitangaben (kompatibel zum Zeitversand des Wiregate) funktionieren.

    Die eigentliche Sprachausgabe erfolgt durch aplay und der Zusammensetzung der vorhandenen wav-Dateien.

    Interesse? Wenn mir jemand erklärt, wie ich den ganzen Kram uploade, tu ich es.

    VG, Fry

    #2
    Hier der Code:

    Code:
    ###########
    # Ansagen #
    ###########
    # Wiregate-Plugin
    # (c) 2012 Fry under the GNU Public License version 2 or later
    
    # $plugin_info{$plugname.'_cycle'}=0; return 'deaktiviert';
    
    use POSIX qw(floor);
    
    # Voraussetzungen:
    
    # 1. Im Verzeichnis $speechdir/Zahlen muessen folgende Dateien vorhanden sein:
    
    # 1.1. Kardinalzahlen ("Null", "Eins"): 
    # c0.wav...c19.wav, c20.wav...c90.wav, c100.wav, c1000.wav
    
    # 1.2. Ordinalzahlen ("Erster", "Zweiter"): 
    # o0.wav...o19.wav, o20.wav...o90.wav, o100.wav, o1000.wav
    
    # 1.3. Zahlteile mit "und" wie "...undzwanzig", "...unddreissigster":
    # uc20.wav...uc90.wav, uo20.wav...uo90.wav
    
    # 1.4. Ziffern zur Zahlbildung ("ein"):
    # u1.wav...u9.wav (u1.wav="ein" als Bestandteil von "einunzwanzig",
    # u2.wav...u9.wav koennen identisch mit c2.wav...c9.wav sein)
    
    # 1.7. Spezielle Woerter:
    # minus.wav, Komma.wav, Grad.wav, Prozent.wav
    # auf.wav, zu.wav, hoch.wav, runter.wav, an.wav, aus.wav
    
    # 2. Im Verzeichnis $speechdir/Monate muessen die Namen der Monate liegen:
    # Januar.wav ... Dezember.wav
    
    # 3. Im Verzeichnis $speechdir/Wochentage muessen die Wochentagsnamen liegen:
    # Mo.wav ... So.wav 
    
    # 4. Ein Piepton $speechdir/beep.wav mit Pieptoenen, die vor der Sprachausgabe
    # gesendet werden (weckt bei mir den Russound-Paging-Kanal auf, der sonst die
    # ersten Silben verschluckt). Bei mir ist das wiederum ein ganzes Verzeichnis 
    # Beep mit Dateien 01.wav ... 32.wav in aufsteigender Dauer sortiert
    
    # 5. Im Verzeichnis $speechdir ausserdem: 
    # Alle Woerter bzw. ganze Saetze, die vorgelesen werden sollen,
    # wobei zB ein Satz "Willkommen Fry" in der Datei $speechdir/Willkommen/Fry.wav
    # liegen darf
    
    # alle diese Audiodateien kann man sich online generieren, zB bei SVOX.
    
    # Plugin-Konfiguration ################################################
    
    # Ausgabekanal:
    # Die ALSA-Kanalunterscheidung wird durch die Namensgebung der GA 
    # in eibga.conf getroffen. Das Muster ffuer dieKanalunterscheidung
    # steht in %channels.
    
    # Textteil: Der Rest des GA-Namens wird als Text "vorgelesen".
    # Das Plugin sucht dabei zunaechst nach einem "exact match" einer Datei
    # im Sprachverzeichnis. Wenn dieser Match nicht existieren sollte, werden 
    # die Woerter getrennt und jedes einzeln gesucht.
    
    # Datenteil:
    # Am Ende des Textteils wird der Telegramminhalt aufgesagt, 
    # wobei folgende Datentypen erlaubt sind:
    # 1.017: (keine Daten, nur den GA-Namen vorlesen)
    # 1.001: "An/Aus"
    # 1.008: "Hoch/Runter"
    # 1.009: "Auf/Zu"
    # 5.010 / 7.001: Ordinalzahl ("Einundzwanzigster")
    # 6.010 / 8.001: Kardinalzahl ("Einundzwanzig")
    # 6.001 / 5.001: Prozentwert ("dreiundfuenfzig Prozent")
    # 9.001: Temperatur ("minus drei komma fuenf Grad")
    # 11.001: # Datum ("elfter April")
    # 10.001: # Wochentag+Uhrzeit ("Montag elf Uhr fuenfzehn")
    
    # Hier meine Konfiguration als Beispiel:
    
    # ANsagen gehen auf ALSA-Kanal 'welcome' und kommen ueber einen eigenen 
    # kleinen Verstaerker im Eingangsflur raus
    
    # DURCHsagen gehen auf ALSA-Kanal 'paging' und gehen ueber die Russound an 
    # alle Lautsprecher im Haus. Dort muss ein Beep vorweggesendet werden
    
    my $logfile='/var/log/Ansagen.log';
    my $speechdir='/var/lib/Ansagen/Sprache/';
    my %channels=(
        '^WA_'=>'welcome', # zB "WA_Die Aussentemperatur betraegt" 
        '^WD_'=>'paging',  # zB "WD_Folgende Fenster sind geoeffnet"
        'default'=>'welcome' # die GAs in additional_subscriptions
    );
    my $beepchannel='paging';
    my $beep = sprintf "Beep/%02d.wav", 3; # int(rand(32))+1 fuer Zufallsbeep
    #my @additional_subscriptions=qw(0/7/245 0/7/246 6/2/186);
    my @additional_subscriptions=();
    
    ############### Ende der Konfiguration #########################
    
    # Aufrufgrund ermitteln
    my $event=undef;
    if (!$plugin_initflag) 
    { $event='restart'; } # Restart des daemons / Reboot
    elsif ((stat('/etc/wiregate/plugin/generic/' . $plugname))[9] > time()-10) 
    # ab PL30:
    # elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'})
    { $event='modified'; } # Plugin modifiziert
    elsif (%msg) { $event='bus'; } # Bustraffic
    elsif ($fh) { $event='socket'; } # Netzwerktraffic
    else { $event='cycle'; } # Zyklus
    
    chdir $speechdir;
    
    if($event=~/restart|modified/)
    {
        my %gas=();
    
        # Erstaufruf - an GAs anmelden, auf die die Muster in %channels zutreffen
        for my $ga (keys %eibgaconf)
        {
        my $name=$eibgaconf{$ga}{'name'};
        next unless defined $name;
    
        for my $pat (keys %channels)
        {
            next if $pat eq 'default';
    
            if($name=~/$pat/)
            {
            $plugin_subscribe{$ga}{$plugname}=1;
            $gas{$channels{$pat}}++;
            }
        }
        }
    
        for my $ga (@additional_subscriptions)
        {
        $plugin_subscribe{$ga}{$plugname}=1;
        $gas{$channels{default}}++;
        }
    
        $plugin_info{$plugname.'_cycle'}=0;
        
        return join ' ', map $_.'->'.$gas{$_}, keys %gas; 
    }
    elsif($event=~/bus/ && $msg{'apci'} eq 'A_GroupValue_Write')
    {
        my $ga=$msg{'dst'};
        my $dpt=$eibgaconf{$ga}{'DPTSubId'};
        $dpt=1.017 unless defined $dpt; # = Trigger, bedeutet Textansage ohne Daten
        
        my $name=$eibgaconf{$ga}{'name'};   
        my $channel=$channels{default};
        my $pattern=$name;
    
        for my $pat (keys %channels)
        {
        if($pattern=~s/$pat//)
        {
            $channel=$channels{$pat};
            last;
        }
        }
    
        # Hole alle verfuegbaren Durchsagedateien 
        my $find=checkexec('find');
        my @speech=split /\n/, `$find . -name "*.wav"`;
        
        return 'no speech files found' unless @speech;
        
        my @statement=();
        
        # Textteil (Gruppenadresse ausgesprochen)
        if(defined $pattern)
        {
        push(@statement, words(\@speech, $pattern));
        }
        
        # Informationsteil (Inhalt des Telegramms)
        if($dpt == 1.017) 
        {
        # kein Datenzusatz
        }
        elsif($dpt == 1.001) # An/Aus
        {
        push(@statement, 'Zahlen/'.($msg{'value'}?'an':'aus').'.wav');
        }
        elsif($dpt == 1.008) # Hoch/Runter
        {
        push(@statement, 'Zahlen/'.($msg{'value'}?'hoch':'runter').'.wav');
        }
        elsif($dpt == 1.009) # Auf/Zu
        {
        push(@statement, 'Zahlen/'.($msg{'value'}?'auf':'zu').'.wav');
        }
        elsif($dpt == 5.010 || $dpt == 7.001) # Ordinalzahl
        {
        push(@statement, number(\@speech, $msg{'value'}, -1));
        }
        elsif($dpt == 6.010 || $dpt == 8.001) # Kardinalzahl
        {
        push(@statement, number(\@speech, $msg{'value'}));
        }
        elsif($dpt == 6.001 || $dpt == 5.001) # Prozent
        {
        push(@statement, number(\@speech, $msg{'value'}));
        push(@statement, 'Zahlen/Prozent.wav');
        }
        elsif($dpt == 9.001) # Temperatur
        {
        push(@statement, number(\@speech, $msg{'value'}, 1));
        push(@statement, 'Zahlen/Grad.wav');
        }
        elsif($dpt == 11.001) # Datum
        {
        if($msg{'value'}=~/^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])/)
        {
            my @monat=qw(Januar Februar Maerz April Mai Juni Juli August September Oktober November Dezember);
            push(@statement, number(\@speech, $3, -1));
            push(@statement, 'Monate/'.$monat[$2-1].'.wav') if defined $2 && $2>0 && $2<13;
        }
        else
        {
            return "Unbekanntes Datumsformat $msg{value}";
        }
        }
        elsif($dpt == 10.001) # Uhrzeit
        {
        if($msg{'value'}=~/^(Mo|Di|Mi|Do|Fr|Sa|So)\s+([0-9][0-9])\:([0-9][0-9])/)
        {
            push(@statement, "Wochentage/$1.wav");
            push(@statement, number(\@speech, $2));
            push(@statement, "Zeiten/Uhr.wav");
            push(@statement, number(\@speech, $3));
        }
        elsif($msg{'value'}=~/^([0-9][0-9])\:([0-9][0-9])}\:([0-9][0-9])/)
        {
            push(@statement, number(\@speech, $2));
            push(@statement, "Zeiten/Uhr.wav");
            push(@statement, number(\@speech, $3));
        }
        else
        {
            return "Unbekanntes Uhrzeitformat $msg{value}";
        }
        }
        else
        {
        return "Datentyp $dpt nicht implementiert";
        }
        
        # Das komplette Statement in die Ausgabe geben
        speak($channel, $name, @statement);
        
        return $name.' '.$msg{value};
    }
    
    return; 
    
    sub checkexec
    {
        my @path = split /:/, $ENV{PATH};
        map s|(.)/$|$1|, @path;
        for (@path)
        {
            my $full="$_/$_[0]";
            if(-x $full)
            {
                return "$_/$_[0]";
            }
        }
        die "$_[0] must be in your PATH and executable.\n";
    }
    
    
    sub words
    {
        my $speech=shift;
        my $pattern=shift;
    
        # Konstruiere die abzuspielenden File(s) aus dem GA-Kuerzel
        # erster Versuch: eine Datei passt komplett auf das Muster im Kuerzel
        my $pat1=$pattern;
        $pat1=~s/[_\s]+/.*?/g; # allgemeine Fassung
    #    $pat1=~s/\s+.*$//; # meine spezielle GA-Struktur
    #    $pat1=~s/_+/.*?/g; # meine spezielle GA-Struktur
        $pat1='.*'.$pat1.'.*\.wav$';
        
        my @hits=();
        my $hit=bestmatch($speech,$pat1);
        push(@hits, $hit) if $hit; # gefunden
    
        unless(@hits)
        {
        $pattern='_'.$pattern;
        $pattern=~s/\s+/_/g; # allgemeine Fassung
    #    $pattern=~s/\s+.*$//; # meine spezielle GA-Struktur
    
        # zweiter Versuch: aus Kuerzeln die Bausteine zusammenbauen
        while($pattern=~s/^_([^_]+)//)
        {
            my $pat2=$1.'\.wav$'; 
            $hit=bestmatch($speech,$pat2);
            push(@hits, $hit) if $hit; # gefunden
        }    
    
        if($pattern)
        {
            $pattern=~s/_/.*/g; # Restnachricht
            $pattern.='.*\.wav$';
            $pattern='.*'.$pattern;
        
            $hit=bestmatch($speech,$pattern);
            push(@hits, $hit) if $hit; # gefunden
        }
        }
    
        return @hits;
    }
    
    
    sub number
    {
        my $speech=shift;
        my $x=shift; $x=~s/,/./; 
        my $digits=0;  
        $digits=shift if @_; # max. Anzahl Nachkommastellen, -1 fuer Ordinalzahlen
    
        my @hits=();
    
        if($x<0) 
        {
        push(@hits, 'Zahlen/minus.wav');
        $x=-$x;
        $digits=0 if $digits<0; # keine negativen Ordinalzahlen
        }
    
        my $t=$digits<0?'o':'c';
        my $n=floor($x);
        my $m=$x-$n;
    
        # Manche Zahlen existieren direkt als WAV
        # von 0-12, sowie die runden 10er und 100 sowie 1000 
        # MUESSEN existieren, und zwar als Kardinalzahlen (c4.wav),
        # Ordinalzahlen (o6.wav), die Zehner ausserdem mit vorangestelltem 'und'
        # (u30.wav, uo30.wav)
    
        if(-f 'Zahlen/'.$t.$n.'.wav') 
        {
        push(@hits, 'Zahlen/'.$t.$n.'.wav');
        }
        else
        {
        return if($n>=1000000); # Zahlen ueber eine Million nicht implementiert
    
        if($n>=1000)
        {
            $digits=0 if $digits>0; # waere Pseudo-genauigkeit und zu langer Text
            
            if($n==1000)
            {
            push(@hits, 'Zahlen/'.$t.'1000.wav');
            $n = 0;
            }
            else
            {
            my $m=floor($n/1000);
            @hits=number($speech,$m,0) if $m>1;
            $n %= 1000;
            if($n)
            {
                push(@hits, 'Zahlen/c1000.wav');
            }
            else
            {
                push(@hits, 'Zahlen/'.$t.'1000.wav');
            }    
            }
            
            if($n>=100 && $n<200)
            {
            push(@hits, 'Zahlen/u1.wav');
            }
        }
    
        if(-f 'Zahlen/'.$t.$n.'.wav') 
        {
            push(@hits, 'Zahlen/'.$t.$n.'.wav');
        }
        elsif($n>100)
        {
            $digits=0 if $digits>0; # waere Pseudo-genauigkeit und zu langer Text
            my $h = int($n/100);
            $n %= 100;
            push(@hits, 'Zahlen/u'.$h.'.wav') if $h>1;
            if($n)
            {
            push(@hits, 'Zahlen/c100.wav');
            }
            else
            {
            push(@hits, 'Zahlen/'.$t.'100.wav');
            }    
        }
        
        my $d = $n % 10;
        
        if(-f 'Zahlen/'.$t.$n.'.wav') 
        {
            push(@hits, 'Zahlen/'.$t.$n.'.wav');
        }
        else
        {
            my $z = $n-$d;
            
            push(@hits, 'Zahlen/u'.$d.'.wav');
            push(@hits, 'Zahlen/u'.$t.$z.'.wav');
        }
        }
        
        if($digits>0) 
        {
        $m=floor($m*10**$digits)/10**$digits;
        
        if($m>0) 
        {
            push(@hits, 'Zahlen/Komma.wav');
            for (1..$digits)
            {
            $m*=10.; my $d=floor($m); $m-=$d;
            push(@hits, "Zahlen/c$d.wav");
            }
        }
        }
    
        return @hits;
    }
    
    sub bestmatch
    {
        my $speech=shift;
        my $pattern=shift;
    
        my @hits=sort { length($a) cmp length($b) } grep /$pattern/i, @{$speech};
        
        return @hits ? (shift @hits) : undef;
    }
    
    
    sub speak
    {
        my $channel=shift; # ALSA-Channel
        my $name=shift; # Name der Ansage (aus eibga.conf) - fuers Log
    
        open LOG, ">>$logfile";
        my $date=checkexec('date');
        my $datetime=`$date +"%F %X"`;
        $datetime=~s/\s*$//s; 
        
        if(@_)
        {
        my $aplay=checkexec('aplay');
        my $mpc=checkexec('mpc');
        system $mpc, 'pause';
        
        # Nur fuer Russound-Paging: Star Trek 'Beep' vorweg weckt Russound auf
        if($channel=~/$beepchannel/)
        {
            my $lastbeep=$plugin_info{$plugname.'_lastbeep'};
    
            # max ein Beep pro Minute
            if(!defined $lastbeep || time()>$lastbeep+60)
            {
            unshift(@_, $beep);
            $plugin_info{$plugname.'_lastbeep'}=time();
            }
        }
    
        system $aplay, '-c2', "-D$channel", @_;
    
        map s!^.*/(.*?)\.wav!$1!, @_;
        print LOG $datetime.' '.$channel.':'.(join ' ', @_)."\n";
    
        system $mpc, 'toggle';
        }
        else
        {
        print LOG "$datetime $name - keine akustische Ansage moeglich\n";
        }
    
        close LOG;
    }

    Kommentar


      #3
      Setz den Code mal in die Code Tags...

      Kommentar


        #4
        Zitat von vento66 Beitrag anzeigen
        Setz den Code mal in die Code Tags...
        Sorry, aber wie geht das?

        Kommentar


          #5
          ["code"] Dein Code ["/code"] Ohne die Anführungszeichen...

          Kommentar


            #6
            So richtig?

            Kommentar


              #7
              Richtig? Weis ich nicht, aber die Icons sind erst mal aus dem code raus

              Kommentar


                #8
                Cool!
                Wäre sehr nett wenn du dein Ordner mit den Files tauscht!


                Hat schon jemand den TTS dienst von AT&T ausprobiert? Wäre auch ne möglichkeit die Dateien zu erstellen. Hab versucht einen link zusammen zu basteln, leider mag es nicht wirklich gehen...

                Hier mal der link:
                Code:
                #!bin/bash
                voice="klara"
                wget "http://192.20.225.36$(curl --data "voice=$voice&txt=$*&speakbutton=SPEAK" "http://192.20.225.36/tts/cgi-bin/nph-talk" | grep ".wav" | cut -d\" -f2)" -O hallo.wav
                also ./scriptname Text_der_gesprochen_werden_soll

                Wäre mpd eine alternative für dein Plugin? aplay hängt bei mir desöfteren. Ich hatte mich vor einiger Zeit an was ähnlichem Versucht... Bis google so langsam wurde Dort hab ich eine mpd Playlist zusammengebaut. Leider aus festen Dateinamen die "live" erstellt werden. Geht etwas in der Art bei svox auch? Hab leider nichts gefunden.

                Respekt cooles Script!

                Gruß
                Angehängte Dateien

                Kommentar


                  #9
                  Das Plugin steht jetzt (upgedatet) im SVN, und im Haupt-Thread findet ihr auch die Sprachdateien.

                  ATT hatte ich zuerst ausprobiert, SVOX gefällt mir einfach besser.

                  VG,
                  Fry

                  Kommentar


                    #10
                    Hi,

                    würde dein Script gerne Testen. Irgendwie versteh ich die funktionsweise nicht ganz.
                    Steh da gerade auf dem Schlauch.

                    die eibga.conf ist die Wiregate eigene conf? Oder muss ich die in die Plugin config schieben?

                    Wenn die Wiregate eigene, wird der gespeicherte Name der GA verwendet? (würde sich anbieten eine ganze Reihe von GA´s die benötigt werden einfach in der ETS als Dummy und unverknüpft zu erstellen? Mit dem Richtigen DPT-> Dummy applikation)

                    Das Muster der Automatisch gewählten GA´s soll in %channels stehen. Da steht:
                    ^WA_
                    ^WD_
                    Dass heißt deine Namen der Ansage GA´s beinhalten WA oder WD??

                    in Additional GA´s wie im auskommentierten Bsp. die GA´s eintragen?

                    Gruß vlamers

                    Kommentar


                      #11
                      Hi vlamers,

                      Ein möglicher Weg ist beispielsweise folgender:

                      1. Erstelle in der ETS neue Gruppenadressen mit Namen (nicht "Beschreibung"), ich nehme mal zum Beispiel

                      '1/1/23' "Ansage GutenMorgen"

                      '1/1/24' "Ansage Aussentemperatur"

                      '1/1/25' "Ansage Rauchalarm"

                      2. Exportiere diese GAs zum Wiregate (Web-Importinterface - ich kann dazu nichts erklären, weil ich es nicht nutze)

                      2a. Alternativ: erstelle die GAs direkt im Wiregate (Datei /etc/wiregate/eibga.conf)

                      3. Sorge dafür, dass die GAs den Datentyp 10.001 (Uhrzeit) bzw. 9.001 (Temperatur) bzw. 1.017 (Trigger) bekommen - Trigger steht für eine Ansage ohne angehängte Daten. In der ETS geht das bspw, indem du die GAs an entsprechende Kommunikationsobjekte, bspw deiner Wetterstation verbindest (Zeitversand, Termperaturfühler, Switch). Im Wiregate geht das einfach, indem du die GAs mit dem Zeitversand und Temperaturfühler verbindest.

                      3a Alternativ: trage die DPTSubId direkt im Wiregate (Datei /etc/wiregate/eibga.conf) ein

                      3b Alternativ: trage die DPTSubIds gar nicht ein, aber rufe sie mit direkter Angabe der DPTSubId im knx_write-Befehl eines anderen Plugins auf. Also zB

                      Code:
                      knx_write('1/1/24',23.5, 9.001); # 23.5 Grad
                      (das Schreiben von Datum/Uhrzeit per knx_write geht im Wiregate PL30 noch nicht. Ich habe hier im Forum einen entsprechenden Patch des Daemons veroeffentlicht, mit dem das geht - aber mach das nur, wenn du weißt was du tust - ich kann zeitlich keinen extensiven Support leisten).

                      4. Trage die beiden o.g. GAs in der Plugin-Konfiguration mit an.

                      Code:
                      %channels=('^Ansage'=>'default');
                      ('default' ist der ALSA-Kanal für die Ausgabe)

                      oder aber direkt mit den GA-Nummern (ich hasse es, "nackte" Zahlen zu schreiben) unter additional_subscriptions

                      Damit wird dem Ansagen.pl-Plugin beim nächsten Initialisieren klar, dass alle GAs, die mit dem Wort "Ansage" beginnen, Ansagen sind, und das Plugin wird diese GAs subscriben.

                      5. Nun musst du noch dafür sorgen, dass die Dateien /var/lib/Ansagen/Sprache/GutenMorgen.wav, /var/lib/Ansagen/Sprache/Aussentemperatur.wav usw. existieren, dass ALSA (aplay) funktioniert, und natürlich Verstärker+Lautsprecher anschließen (Vorsicht: die aplay-Ausgabe ist standardmäßig MONO auf nur einem Kanal, ich glaube links).

                      6. Have fun!

                      VG, Fry

                      Kommentar


                        #12
                        Vielen Dank für die Ausführliche Antwort!

                        Mir war nicht ganz klar was die GA Namen mit der Ansage zu tun haben.
                        Die Google Stimme war (in normaler Geschw.) für den WAF besser. Leider ist die sehr langsam geworden.

                        Ich nutze mein WG als multiroom Ersatz mit pulseaudio und mpd.
                        Bei mir funktioniert aplay im Zusammenspiel mit pulseaudio nicht. Eine Änderung auf paplay im Script macht dass ganze wieder gangbar. Wäre evtl ein Hinweis im Script wert falls dass jemand nicht weiß.

                        Kann man bei svox die wav Files ähnlich wie bei Google automatisch generieren und runterladen? Würde ein Haufen Tipp arbeit sparen (von der du schon dass meiste bereit gestellt hast). Und die Namen so wie du dass machst vergeben? Also:

                        wget http://svox.com/blabla_Text=$GA_wert -w /var/lib/Ansage/$GA_wert.wav

                        Bei Google ging dass relativ einfach/schön. Leider muss ich jetzt alles umbauen... aber sonst wird's ja langweilig.

                        Gruß

                        ***censored***

                        Kommentar


                          #13
                          Bei SVOX Files automatisch holen? Sicher möglich, aber ich hab's eben händisch gemacht. Soooo viele waren es ja dann auch nicht.

                          Abgesehen davon: das Ansage-Plugin lässt sich problemlos auch für andere Quellen von Sprachfiles anpassen. Bitte gerne machen! - und dann wieder ins SVN, ganz nach dem Motto der GPL2 - jeder darf's verbessern, aber bitte wieder zurück in die Community spielen!

                          Grüße, Fry

                          Kommentar


                            #14
                            Hi,

                            ich muss gestehen dass ich zu doof bin dein Script zu ändern . Sobald ich etwas versuche "anzupassen" geht gar nix mehr...

                            Ansagen tut er gut. Aber man hat ja nur statische Sätze. (und meine Kids sind vor der Stimme erschrocken , die sind noch Miss Google gewöhnt)

                            Ich habe mir alle Ansagen bis jetzt live generieren lassen(google). Dass müsst man nur irgendwie so zerlegen dass er die Sätze in ein extra file speichert, mit dem Text als Namen.
                            So könnte man den Satz ändern, und dass File würde automatisch generiert und abgeholt werden. Derzeit nur bei google und at&t möglich. svox schickt mir kaputte wav files?
                            Aber mit den linux tools wie grep sed cut etc. steh ich auf Kriegsfuss wenn es darum geht nur ein bestimmtes fragment eines Satzes zu lesen... Dass übe ich jetzt erstmal.

                            Gruß

                            Kommentar


                              #15
                              "ich muss gestehen dass ich zu doof bin dein Script zu ändern"

                              Sorry, vlamers, aber bei dieser "Fehlerbeschreibung" kann ich leider nichts machen :-)

                              "Sobald ich etwas versuche "anzupassen" geht gar nix mehr..."

                              Was würdest du denn gerne anpassen. Wie funktioniert das denn mit "Miss Google" (ich habe keine Ahnung, was das ist)

                              "Ansagen tut er gut. Aber man hat ja nur statische Sätze."

                              Mehr brauche ich auch nicht. Mein Haus ist ja auch statisch, und da im vorliegenden Plugin einfach die GA-Namen "vorgelesen" werden, ist der Wortschatz durch die (statische) GA-Struktur limitiert. Oder welche Anwendung hast du vor? (Vermutlich was ganz anderes als ich...)

                              "und meine Kids sind vor der Stimme erschrocken , die sind noch Miss Google gewöhnt"

                              Also sooo schlimm ist SVOX nicht, da finde ich ATT deutlich schlechter. Miss Google kenne ich nicht (bitte ein Link)

                              "Ich habe mir alle Ansagen bis jetzt live generieren lassen(google). Dass müsst man nur irgendwie so zerlegen dass er die Sätze in ein extra file speichert, mit dem Text als Namen."

                              Besser wäre es, das Skript lädt Sätze, die es nicht kennt, automatisch und "cached" sie lokal. Kann ich hacken, wenn du mir sagst, was du eigentlich genau brauchst.

                              "Aber mit den linux tools wie grep sed cut etc. steh ich auf Kriegsfuss wenn es darum geht nur ein bestimmtes fragment eines Satzes zu lesen... Dass übe ich jetzt erstmal."

                              Übe einfach perl. Der Rest (awk sed grep) ist obsolet und durch Perl viel eleganter ersetzbar.

                              Grüße,
                              Fry

                              Kommentar

                              Lädt...
                              X