kramann.info
© Guido Kramann

Login: Passwort:










6.1 Erweiterung der Android-Processing-VR-Funktionalität um den Befehl "sprich(String)"

6.1 (EN google-translate)

6.1 (PL google-translate)

Der Sprachsynthesizer wurde bereits mehrfach in vorangehend besprochenen Sketches benutzt. Nun geht es mehr darum, ihn sinnvoll zu modularisieren. Insbesondere gilt es dabei, die Komplexität der zugehörigen Programmstruktur für den "Benutzer-Programmierer" zu verbergen, die insbesondere darin besteht...

The speech synthesizer has been used several times in previously discussed sketches. Now it's more about making it useful to modularize. In particular, it is the complexity of the associated program structure for the To hide user programmers, which in particular consists of ...

Syntezator mowy był używany kilkakrotnie w omawianych wcześniej szkicach. Teraz chodzi bardziej o to, aby było ono przydatne do modularyzacji. W szczególności jest to złożoność powiązanej struktury programu dla Aby ukryć programistów użytkownika, który w szczególności składa się z ...

  • ... überhaupt den Sprachsynthesizser anzusprechen, bzw. initialisieren,
  • ... bei schnellem mehrmaligem Aufruf von "sprich(String)" dafür zu sorgen, dass ein neuer Text erst synthetisiert wird, wenn eine vorangehende Synthetisierung beendet wurde.

Lazy Binding

Lazy Binding

Lazy Binding

Nicht in jedem Programm wird die Sprachsynthese benötigt werden. Andererseits möchte man für die einfache Benutzung nicht gerne noch einen Konstruktor bei Bedarf aufrufen müssen.

Not every program will require speech synthesis. On the other hand, you do not want to have one for easy use If necessary, call the constructor.

Nie każdy program wymaga syntezy mowy. Z drugiej strony, nie chcesz go mieć do łatwego użytku Jeśli to konieczne, zadzwoń do konstruktora.

Eine Lösung für dieses Problem stellt die Verwendung des s.g. Lazy-Binding dar: Programmstrukturen, die nicht immer benötigt werden, werden erst initialisiert und geladen, wenn sie das erste mal benutzt werden sollen. Im konkreten Fall kann mit Aufrufen der Funktion "sprich(String)" jedesmal geprüft werden, ob das Sprach-Synthesizer-Objekt "null" ist und ggf. der Konstruktor aufgerufen werden.

One solution to this problem is the use of the s.g. Lazy Bindin Program structures that are not always needed are first initialized and loaded, if they are to be used for the first time. In the specific case can with calls of t if necessary, call the constructor.

Jednym z rozwiązań tego problemu jest zastosowanie s.g. Lazy Bindin Struktury programu, które nie zawsze są potrzebne, są najpierw inicjowane i ładowane, jeśli mają być użyte po raz pierwszy. W konkretnym przypadku można z połączeń jeśli to konieczne, zadzwoń do konstruktora.

Umsetzung

implementation

realizacja

In der folgenden Realisierung kann nach Übernahme des Tabs "Zusatz" in einen beliebigen Sketch (für VR-Android) im Hauptprogramm der Sprachsynthesizer einfach durch Verwendung der Funktion sprich("Mein Text"); verwendet werden:

In the following implementation, after taking over the tab, you can add in any sketch (for VR-Android) in the main program of the speech synthesizer simply by using the function speak (My

W poniższej implementacji, po przejęciu zakładki, możesz dodać dowolny szkic (dla VR-Android) w głównym programie syntezatora mowy po prostu używając funkcji speak (My

Sprich.zip - Processing-Sketch.
import processing.vr.*;


//ACHTUNG:
//Android->VR anhaken

PMatrix3D eyeMat = new PMatrix3D();

String zeichen = "ABCDEFGHIJKLMNOPQRSTUVWXZ";

int RESTZEIT = 0;
String[] AUSWAHL = {"1","2","3"};
int inx=0;

void setup() 
{
    fullScreen(MONO);
}


void draw() 
{
  //Standardeinstellungen für unser Arbeiten:
  background(0);
  getEyeMatrix(eyeMat); //Kameramatrix auslesen  
  translate(eyeMat.m03, eyeMat.m13, eyeMat.m23); //Welt in Koordinatenursprung von Kamera setzen.
  lights();
  float ez_x =  eyeMat.m02;  //Einheitsvektor der aktuellen Blickrichtung
//  float ez_y =  -eyeMat.m12;
  float ez_y =  eyeMat.m12;
  float ez_z =  eyeMat.m22;  
  
  //ENDE Standardeinstellungen für unser Arbeiten:
 
  //Buchstaben auf "Platten" zeichnen:
  textSize(64);
  for(int i=0;i<zeichen.length();i++)
  {
      pushMatrix();
      
      float z = -500.0f;
      float y = - 200 + (i/5)*100;
      float x = 100*(i%5) - 200;

      //Nähe zum Zielkreis:
      
      //1) Einheitsvektor bilden:
      float laenge = sqrt(x*x+y*y+z*z);
      float xx=x/laenge;
      float yy=y/laenge;
      float zz=z/laenge;
      
      //2) Skalarprodukt mit Blickrichtung (ez)      
      float sk = xx*ez_x + yy*ez_y + zz*ez_z;
      
      if(sk>0.99f && RESTZEIT==0)
      {
           AUSWAHL[inx]=zeichen.substring(i,i+1);
           inx++;
           inx%=AUSWAHL.length;
           
           if(AUSWAHL[0].equals(AUSWAHL[1]) && AUSWAHL[1].equals(AUSWAHL[2]))
           {
                sprich(AUSWAHL[0]);
                AUSWAHL[0] ="1";
                AUSWAHL[1] ="2";
                AUSWAHL[2] ="3";
           }
           
           RESTZEIT = 30;
      }
      
      translate(x,y,z); 
      noStroke();
      fill(0,255,0);
      text(zeichen.substring(i,i+1),-20,20);
      popMatrix();
      
  }
  
  //Zielkreis zeichnen
  eye(); //Transformation realtiv zur Kamera
  translate(0, 0, 95); //Zielkreis relativ zur Kamera zeichnen
  noFill();
  stroke(255,0,0);
  ellipse(0, 0, 10, 10);
  
  if(RESTZEIT>0)
      RESTZEIT--;
}

Code 6.1-1: Sprich.pde

//TTS:
import android.speech.tts.TextToSpeech;
import java.util.Locale;
import java.util.Set;
import android.media.AudioManager;
import android.content.Context;

TTS tts = null;

public void sprich(String text)
{
    if(tts==null)
    {
        tts = new TTS();
        tts.setzeSpechgeschwindigkeit(1.0f);
        tts.setzeStimmhoehe(1.0f);
        tts.setzeLautstaerke(0.8f);      
    }
    
    if(tts!=null)
    {
        tts.sprich(text);
    }
}

public class TTS implements Runnable
{
     ArrayList<String> warteschlange = new ArrayList<String>();
  
  
     TextToSpeech tts;
     AudioManager audio;
     int currentVolume;
     int maxVolume;

     public void setzeSpechgeschwindigkeit(float s)
     {
         tts.setSpeechRate(s);    
     }

     public void setzeStimmhoehe(float h)
     {
         tts.setSpeechRate(h);    
     }

     public void setzeLautstaerke(float ls)
     {
         if(ls<0.0f)
             ls=0.0f;
         if(ls>1.0f)
             ls=1.0f;
         int LAUT  = (int) (maxVolume*ls);
             
         audio.setStreamVolume(AudioManager.STREAM_MUSIC, LAUT, 0);             
     }

     public void run()
     {
         while(true)
         {
              if(tts!=null && warteschlange.size()>0 && !tts.isSpeaking())
              {
                  String text = warteschlange.get(0);
                  warteschlange.remove(0);
                
                  tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
              }  
                         
              try
              {
                  Thread.sleep(100);
              }
              catch(Exception e)
              {
              }
         }
     }

     public void sprich(String text)
     {
        warteschlange.add(text);       
     }

     public TTS()
     {
         //NEU:  getActivity(). ab Proc. 3!
         tts=new TextToSpeech(getActivity().getApplicationContext(), new TextToSpeech.OnInitListener() {
         //@Override
            public void onInit(int status) {
               if(status != TextToSpeech.ERROR) {
                  tts.setLanguage(Locale.GERMAN);
               }
            }
         });

         audio = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);  //NEU:  getActivity(). ab Proc. 3!
         currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
         maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         
         //eigenen Thread starten:
         (new Thread(this)).start();
     }
}

Code 6.1-2: Zusatz.pde