0

Gestern stelle ich eine vereinfachte Frage meines Problems, denke aber, dass es zu vereinfacht ist.Google Erkenner und PocketSphinx in zwei verschiedenen Klassen, wie man sie schlingen?

Was mein Programm tun sollte, ist ein Schlüsselwort zu hören und wenn er es hört, sollte er auf das hören, was ich gesagt habe. (wie wenn du Siri oder Google jetzt gesagt hast, indem du siri sagst oder ok google).

Ich benutze passphinx für das Schlüsselwort und den Google Spracherkennung für die längeren Teile. Es funktioniert, aber nur für eine Zeit. Die Taschensphinx ist in der MainActivity und der Google Recognizer ist in einer extra Klasse (Jarvis).

Das Programm beginnt mit dem Taschensphinx-Listener, wenn er den KEYPHRASE hört, startet er den Google-Listener durch Aufruf von jarvis.startListener() (durch die next() - Methode) und es gibt das Problem, wenn der googlelistener fertig ist Ich komme nicht von der Jarvis-Klasse zur MainActivity zurück, um die next() -Methode erneut aufzurufen.

(wenn die Google-Erkenner im onResult geschehen ist, sind er die letzten Dinge tun() in Jarvis-Klasse, aber von dort kann ich nicht die nächste() aufrufen - Methode von MainActivity-Klasse)

MainActivity

package com.example.superuser.jarvis; 

import android.app.Activity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.speech.RecognitionListener; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.io.File; 
import java.io.IOException; 

import edu.cmu.pocketsphinx.Assets; 
import edu.cmu.pocketsphinx.Hypothesis; 
import edu.cmu.pocketsphinx.SpeechRecognizer; 
import edu.cmu.pocketsphinx.SpeechRecognizerSetup; 

import static android.widget.Toast.makeText; 
import static edu.cmu.pocketsphinx.SpeechRecognizerSetup.defaultSetup; 



public class MainActivity extends Activity implements edu.cmu.pocketsphinx.RecognitionListener { 

    private String LOG_TAG = "Jarvis_hears_anything"; 
    private TextView tv; 
    private Jarvis jarvis; 
    private boolean wannahearjarvis = false; 

    /* Named searches allow to quickly reconfigure the decoder */ 
    private static final String KWS_SEARCH = "wakeup"; 

    /* Keyword we are looking for to activate menu */ 
    private static final String KEYPHRASE = "jarvis"; 

    private edu.cmu.pocketsphinx.SpeechRecognizer recognizer; 
    //private HashMap<String, Integer> captions; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     final Button button = (Button) findViewById(R.id.b1); 
     tv = (TextView) findViewById(R.id.tv1); 
     //captions = new HashMap<String, Integer>(); 
     //captions.put(KWS_SEARCH, R.string.kws_caption); 
     jarvis = new Jarvis(getApplicationContext()); 
     new AsyncTask<Void, Void, Exception>() { 
      @Override 
      protected Exception doInBackground(Void... params) { 
       try { 
        Assets assets = new Assets(MainActivity.this); 
        File assetDir = assets.syncAssets(); 
        setupRecognizer(assetDir); 
       } catch (IOException e) { 
        return e; 
       } 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Exception result) { 
       if (result != null) { 
        ((TextView) findViewById(R.id.tv1)) 
          .setText("Failed to init recognizer " + result); 
       } else { 
        //switchSearch(KWS_SEARCH); 
        recognizer.startListening(KWS_SEARCH); 
       } 
      } 
     }.execute(); 

       button.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         Toast.makeText(getApplicationContext(), "geht", Toast.LENGTH_SHORT).show(); 

        } 
       }); 


    } 

    public void next(){ 
     if (wannahearjarvis){ 
      recognizer.startListening(KWS_SEARCH); 
      wannahearjarvis = false; 
     } 
     else{ 
      jarvis.startListening(); 
      wannahearjarvis = true; 
     } 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     recognizer.cancel(); 
     recognizer.shutdown(); 
    } 

    /** 
    * In partial result we get quick updates about current hypothesis. In 
    * keyword spotting mode we can react here, in other modes we need to wait 
    * for final result in onResult. 
    */ 
    @Override 
    public void onPartialResult(Hypothesis hypothesis) { 
     if (hypothesis == null) 
      return; 

     String text = hypothesis.getHypstr(); 
     if (text.equals(KEYPHRASE)){ 
      tv.append("found"); 
      recognizer.stop(); 
      //switchSearch(KWS_SEARCH); 

     } 
     else { 
      //((TextView) findViewById(R.id.tv1)).append(text+"PR"); 
      //Log.i(LOG_TAG, text+"PR"); 
     } 
    } 

    /** 
    * This callback is called when we stop the recognizer. 
    */ 
    @Override 
    public void onResult(Hypothesis hypothesis) { 
     //((TextView) findViewById(R.id.tv1)).setText(""); 
     ((TextView) findViewById(R.id.tv1)).append("oR"); 
     if (hypothesis != null) { 
      String text = hypothesis.getHypstr(); 
      makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show(); 
     } 

     next(); 
    } 

    @Override 
    public void onBeginningOfSpeech() { 
    } 

    /** 
    * We stop recognizer here to get a final result 
    */ 
    @Override 
    public void onEndOfSpeech() { 
     if (!recognizer.getSearchName().equals(KWS_SEARCH)){ 
      tv.append("fuck"); 
     } 
      //switchSearch(KWS_SEARCH); 
    } 

    /*private void switchSearch(String searchName) { 
     recognizer.stop(); 

     // If we are not spotting, start listening with timeout (10000 ms or 10 seconds). 
     if (searchName.equals(KWS_SEARCH)) 
      recognizer.startListening(searchName); 
     else 
      recognizer.startListening(searchName, 10000); 

     //String caption = getResources().getString(captions.get(searchName)); 

     //((TextView) findViewById(R.id.tv1)).setText(caption); 
     //((TextView) findViewById(R.id.tv1)).append(caption); 
    }*/ 

    private void setupRecognizer(File assetsDir) throws IOException { 
     // The recognizer can be configured to perform multiple searches 
     // of different kind and switch between them 

     recognizer = defaultSetup() 
       .setAcousticModel(new File(assetsDir, "en-us-ptm")) 
       .setDictionary(new File(assetsDir, "cmudict-en-us.dict")) 

         // To disable logging of raw audio comment out this call (takes a lot of space on the device) 
       .setRawLogDir(assetsDir) 

         // Threshold to tune for keyphrase to balance between false alarms and misses 
       .setKeywordThreshold(1e-20f) 

         // Use context-independent phonetic search, context-dependent is too slow for mobile 
       .setBoolean("-allphone_ci", true) 

       .getRecognizer(); 
     recognizer.addListener(this); 

     /** In your application you might not need to add all those searches. 
     * They are added here for demonstration. You can leave just one. 
     */ 

     // Create keyword-activation search. 
     recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE); 

    } 

    @Override 
    public void onError(Exception error) { 
     ((TextView) findViewById(R.id.tv1)).setText(error.getMessage()); 
    } 

    @Override 
    public void onTimeout() { 
     //switchSearch(KWS_SEARCH); 
    } 
} 

Jarvis

package com.example.superuser.jarvis; 

import android.content.Context; 
import android.content.Intent; 
import android.media.AudioManager; 
import android.os.Bundle; 
import android.speech.RecognitionListener; 
import android.speech.RecognizerIntent; 
import android.speech.SpeechRecognizer; 
import android.widget.Toast; 

import java.util.ArrayList; 

    public class Jarvis implements RecognitionListener{ 

    private AudioManager audiom; 
    private SpeechRecognizer speech; 
    private Intent recogIntent; 
    private Toast m; 
    private Context c; 
    private String text; 


    public Jarvis(Context context){ 
     speech = SpeechRecognizer.createSpeechRecognizer(context); 
     speech.setRecognitionListener(this); 
     recogIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
     recogIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "de"); 
     //recogIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName()); 
     m = new Toast(context); 
     c=context; 
    } 

    public void startListening(){ 
     speech.startListening(recogIntent); 
    } 

    public void destroy(){ 
     speech.stopListening(); 
     speech.cancel(); 
     speech.destroy(); 
    } 


    @Override 
    public void onReadyForSpeech(Bundle params) { 

    } 

    @Override 
    public void onBeginningOfSpeech() { 

    } 

    @Override 
    public void onRmsChanged(float rmsdB) { 

    } 

    @Override 
    public void onBufferReceived(byte[] buffer) { 

    } 

    @Override 
    public void onEndOfSpeech() { 

    } 

    @Override 
    public void onError(int error) { 

    } 

    @Override 
    public void onResults(Bundle results) { 
     ArrayList<String> matches = results 
       .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); 
     Toast.makeText(c, matches.get(0), Toast.LENGTH_LONG).show(); 
     speech.cancel(); 
     //tried 
     //MainActivity m = new MainActivity(); 
     //m.next(); 
     //but got a Nullpointer Exception 

    } 

    @Override 
    public void onPartialResults(Bundle partialResults) { 

    } 

    @Override 
    public void onEvent(int eventType, Bundle params) { 

    } 
} 

Antwort

1

Sie Bezug auf die Haupttätigkeit in Jarvis Objekt in einem Feld speichern kann:

class Jarvis { 
    .... 
    private MainActivity m; 
    .... 
    public Jarvis(MainActivity m) { 
     this.m = m; 
    } 
    .... 
    public void onResults(Bundle results) { 
     .... 
     m.next(); 
    } 

Sie können auch Absichten an die Hauptaktivität senden, wie beschrieben here. Dies könnte jedoch in Ihrem Fall übertrieben sein.

+0

Danke, funktioniert gut! Ist es richtig, jarvis in der MainActivity folgendermaßen aufzurufen: Jarvis jarvis = new Jarvis (getApplicationContext(), this); ? es funktioniert, aber ich bin mir nicht sicher, ob es wirklich richtig ist. – Phil

+0

Ja, du kannst es so machen –

Verwandte Themen