0

バックグラウンド認識の目的で Asyntask を使用する Android 音声認識システムを開発しています。私のコードは次のとおりです。音声を認識するためにスタートボタンを押すたびに Asyntask の execute を呼び出したかったのですが、Asyntask は 1 回しか実行できないようでした。もう一度呼び出すとクラッシュします。毎回新しい非同期タスクを作成することはお勧めしません。これをインスタンス化すると、UI スレッドが何百ものフレームをスキップし、ユーザー エクスペリエンスがぎこちなく遅くなるためです。

この問題を解決するにはどうすればよいですか?

public class PocketSphinxAndroidDemo extends Activity {

    private class RecognitionTask
            extends AsyncTask<AudioRecord, Void, Hypothesis> {

        Decoder decoder;
        Config config;


        public RecognitionTask() {


            Config config = Decoder.defaultConfig();

            decoder = new Decoder(config);
        }

        protected void doInBackground(AudioRecord... recorder) {
            int nread;
            short[] buf = new short[1024];

            decoder.startUtt(null);
            while ((nread = recorder[0].read(buf, 0, buf.length)) > 0)
                decoder.processRaw(buf, nread, false, false);
            decoder.endUtt();
            return decoder.hyp();               
        }

        protected void onPostExecute(Hypothesis hypothesis) {
            if (null != hypothesis)
                speechResult.append("\n" + hypothesis.getHypstr());
            else
                speechResult.append("\n<no speech>");
        }
    }

    private static final int SAMPLE_RATE = 8000;

    static {
        System.loadLibrary("pocketsphinx_jni");
    }

    private TextView speechResult;
    private AudioRecord recorder;
    private RecognitionTask recTask;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        speechResult = (TextView) findViewById(R.id.SpeechResult);

        recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_RECOGNITION,
                                   SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
                                   AudioFormat.ENCODING_PCM_16BIT, 8192);
        recTask = new RecognitionTask();
    }

    public void onToggleRecognition(View view) {
        if (!(view instanceof ToggleButton))
            return;

        if (((ToggleButton) view).isChecked()) {
            recorder.startRecording();
            recTask.execute(recorder);
        } else {
            recorder.stop();
        }
    }
}
4

2 に答える 2