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



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

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

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

程序从pocketsphinx监听器开始,当他听到KEYPHRASE时,他通过调用jarvis.startListener()(通过next()-方法)来启动谷歌监听器,但问题是,当谷歌监听器完成后,我不会从jarvis类返回MainActivity再次调用next(()方法。

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

主要活动

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

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

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

您还可以向此处所述的主要活动发送意图。不过,对你来说,这可能有些过头了。

相关内容

  • 没有找到相关文章

最新更新