谷歌识别器和pocketsphinx在两个不同的类中,如何循环它们?

时间:2016-04-04 13:12:52

标签: java android speech-recognition pocketsphinx pocketsphinx-android

昨天我问了一个关于我的问题的简化问题,但认为它太简单了。

我的程序应该做的是听到一个关键词,当他听到这个关键词时,他应该听我说的话。 (就像你现在告诉siri或google,说siri或ok google)。

我正在使用pocketsphinx作为关键字,谷歌语音识别器用于较长的部分。它有效,但只有一次。 pocketsphinx位于MainActivity中,谷歌识别器属于额外级别(Jarvis)。

程序从pocketsphinx监听器开始,当他听到KEYPHRASE时,他通过调用jarvis.startListener()(通过next() - 方法)启动google监听器,并且当googlelistener完成时出现问题,我不会从Jarvis类返回到MainActivity再次调用next()方法。

(当谷歌识别器完成时,他做的最后一件事是在Jarvis-class的onResult()中,但从那里我不能从MainActivity类调用next() - 方法)

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);
    }
}

贾维斯

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 个答案:

答案 0 :(得分:1)

您可以在字段中存储对Jarvis对象中主要活动的引用:

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

您还可以按照here所述向主要活动发送意图。在你的情况下,这可能是过度的。