/* * Copyright 2011 Greg Milette and Adam Stroud * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package root.gast.speech.voiceaction; import java.util.List; import root.gast.speech.SpeechRecognizingActivity; import root.gast.speech.tts.TextToSpeechUtils; import android.annotation.SuppressLint; import android.content.Intent; import android.os.Build; import android.speech.RecognizerIntent; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener; import android.speech.tts.UtteranceProgressListener; import android.util.Log; /** * Helps execute {@link VoiceAction}s and say their responses and prompts. * @author Greg Milette <<a * href="mailto:gregorym@gmail.com">gregorym@gmail.com</a>> */ @SuppressLint("NewApi") public class VoiceActionExecutor { private static final String TAG = "VoiceActionExecutor"; private VoiceAction active; private SpeechRecognizingActivity speech; /** * parameter for TTS to identify utterance */ private final String EXECUTE_AFTER_SPEAK = "EXECUTE_AFTER_SPEAK"; private TextToSpeech tts; public VoiceActionExecutor(SpeechRecognizingActivity speech) { this.speech = speech; active = null; } /** * set the tts when it is ready to complete initialization */ @SuppressLint("NewApi") public void setTts(TextToSpeech tts) { this.tts = tts; if (Build.VERSION.SDK_INT >= 15) { tts.setOnUtteranceProgressListener(new UtteranceProgressListener() { @Override public void onDone(String utteranceId) { onDoneSpeaking(utteranceId); } @Override public void onError(String utteranceId) { } @Override public void onStart(String utteranceId) { } }); } else { Log.d(TAG, "set utternace completed listener"); tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() { @Override public void onUtteranceCompleted(String utteranceId) { onDoneSpeaking(utteranceId); } }); } } /** * external handleReceiveWhatWasHeard must call this */ public void handleReceiveWhatWasHeard(List<String> heard, float[] confidenceScores) { active.interpret(heard, confidenceScores); } private void onDoneSpeaking(String utteranceId) { if (utteranceId.equals(EXECUTE_AFTER_SPEAK)) { doRecognitionOnActive(); } } /** * convenient way to just reply with something spoken */ public void speak(String toSay) { tts.speak(toSay, TextToSpeech.QUEUE_FLUSH, null); } /** * add speech, don't flush the speaking queue */ public void addSpeech(String toSay) { tts.speak(toSay, TextToSpeech.QUEUE_ADD, null); } /** * execute the current active {@link VoiceAction} again speaking * extraPrompt before */ public void reExecute(String extraPrompt) { if ((extraPrompt != null) && (extraPrompt.length() > 0)) { tts.speak(extraPrompt, TextToSpeech.QUEUE_FLUSH, TextToSpeechUtils.makeParamsWith(EXECUTE_AFTER_SPEAK)); } else { execute(getActive()); } } /** * change the current voice action to this and then execute it, optionally * saying a prompt first */ public void execute(VoiceAction voiceAction) { if (tts == null) { throw new RuntimeException("Text to speech not initialized"); } setActive(voiceAction); if (voiceAction.hasSpokenPrompt()) { Log.d(TAG, "speaking prompt: " + voiceAction.getSpokenPrompt()); tts.speak(voiceAction.getSpokenPrompt(), TextToSpeech.QUEUE_FLUSH, TextToSpeechUtils.makeParamsWith(EXECUTE_AFTER_SPEAK)); } else { doRecognitionOnActive(); } } private void doRecognitionOnActive() { Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); recognizerIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, getActive() .getPrompt()); speech.recognize(recognizerIntent); } private VoiceAction getActive() { return active; } private void setActive(VoiceAction active) { this.active = active; } public TextToSpeech getTts() { return tts; } }