0

Вчера я задаю упрощенный вопрос о своей проблеме, но думаю, что это слишком упрощено.Google распознаватель и pocketsphinx в двух разных классах, как их петли?

Что должна моя программа, это услышать ключевое слово, и когда он услышит это, он должен слушать то, что я сказал. (например, если вы сказали siri или google сейчас, сказав siri или ok google).

Я использую pocketsphinx для ключевого слова и речевого распознавателя google для более длинных частей. Он работает, но только за один раз. Pocketsphinx находится в MainActivity, а распознаватель google находится в дополнительном классе (Jarvis).

Программа начинается с прослушивания pocketsphinx, когда он слышит KEYPHRASE, он запускает слушателя Google, вызывая jarvis.startListener() (методом next()), и возникает проблема, когда googlelistener завершен , я не возвращаюсь из класса Jarvis в MainActivity, чтобы снова вызвать метод next().

(когда распознаватель Google будет сделано, последнее, что он делает это в onResult() в Jarvis-классе, но оттуда я не могу назвать следующий() - метод из MainActivity-класса)

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

    } 
} 

ответ

1

Вы можете хранить ссылку на основной деятельности в объекте Jarvis в поле:

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

Вы также можете отправить намерения в основной вид деятельности, как описано here. Однако это может быть излишним в вашем случае.

+0

Спасибо, работает отлично! Правильно ли вызывать jarvis в MainActivity следующим образом: Jarvis jarvis = new Jarvis (getApplicationContext(), this); ? он работает, но я не уверен, действительно ли он прав. – Phil

+0

Да, вы можете это сделать –

Смежные вопросы