0

Hier, je pose une question simplifiée de mon problème, mais pense que c'est trop simplifié. Ce que mon programme devrait faire, c'est entendre un mot-clé et quand il l'entendra, il devrait écouter ce que j'ai dit. (comme si vous disiez à siri ou google maintenant, en disant siri ou ok google). J'utilise pocketsphinx pour le mot-clé et le google speechrecognizer pour les parties plus longues. Cela fonctionne, mais seulement pour une fois. Le pocketsphinx est dans le MainActivity et le google recognizer est dans une classe supplémentaire (Jarvis). Le programme commence avec l'écouteur pocketsphinx, quand il entend KEYPHRASE, il lance l'écouteur google en appelant jarvis.startListener() (par la méthode next()) et il y a le problème, quand le googlelistener est terminé , je ne reviens pas de la classe Jarvis à MainActivity pour appeler à nouveau la méthode next().Google Recognizer et pocketsphinx dans deux classes différentes, comment les boucler?

(lorsque la reconnaissance Google est fait, les dernières choses qu'il faire est dans le onResult() à Jarvis-classe, mais à partir de là je ne peux pas appeler le prochain() - méthode de MainActivity classe)

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) { 

    } 
} 

Répondre

1

Vous pouvez stocker référence à l'activité principale dans l'objet Jarvis dans un champ:

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

Vous pouvez également envoyer des intentions à l'activité principale comme décrit here. Cela pourrait être exagéré dans votre cas si.

+0

Merci, ça marche bien! Est-ce correct d'appeler jarvis dans MainActivity comme ceci: Jarvis jarvis = new Jarvis (getApplicationContext(), this); ? cela fonctionne mais je ne suis pas sûr si c'est vraiment juste. – Phil

+0

Oui, vous pouvez le faire de cette façon –