/*
* Copyright 2012 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.activation;
import java.util.List;
import root.gast.speech.SpeechRecognitionUtil;
import root.gast.speech.text.WordList;
import root.gast.speech.text.match.SoundsLikeWordMatcher;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
/**
* Uses direct speech recognition to activate when the user speaks
* one of the target words
* @author Greg Milette <<a
* href="mailto:gregorym@gmail.com">gregorym@gmail.com</a>>
*/
public class WordActivator implements SpeechActivator, RecognitionListener
{
private static final String TAG = "WordActivator";
private Context context;
private SpeechRecognizer recognizer;
private SoundsLikeWordMatcher matcher;
private SpeechActivationListener resultListener;
public WordActivator(Context context,
SpeechActivationListener resultListener, String... targetWords)
{
this.context = context;
this.matcher = new SoundsLikeWordMatcher(targetWords);
this.resultListener = resultListener;
}
@Override
public void detectActivation()
{
recognizeSpeechDirectly();
}
private void recognizeSpeechDirectly()
{
Intent recognizerIntent =
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
// accept partial results if they come
recognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
SpeechRecognitionUtil.recognizeSpeechDirectly(context,
recognizerIntent, this, getSpeechRecognizer());
}
public void stop()
{
if (getSpeechRecognizer() != null)
{
getSpeechRecognizer().stopListening();
getSpeechRecognizer().cancel();
getSpeechRecognizer().destroy();
}
}
@Override
public void onResults(Bundle results)
{
Log.d(TAG, "full results");
receiveResults(results);
}
@Override
public void onPartialResults(Bundle partialResults)
{
Log.d(TAG, "partial results");
receiveResults(partialResults);
}
/**
* common method to process any results bundle from {@link SpeechRecognizer}
*/
private void receiveResults(Bundle results)
{
if ((results != null)
&& results.containsKey(SpeechRecognizer.RESULTS_RECOGNITION))
{
List<String> heard =
results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
float[] scores =
results.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES);
receiveWhatWasHeard(heard, scores);
}
else
{
Log.d(TAG, "no results");
}
}
private void receiveWhatWasHeard(List<String> heard, float[] scores)
{
boolean heardTargetWord = false;
// find the target word
for (String possible : heard)
{
WordList wordList = new WordList(possible);
if (matcher.isIn(wordList.getWords()))
{
Log.d(TAG, "HEARD IT!");
heardTargetWord = true;
break;
}
}
if (heardTargetWord)
{
stop();
resultListener.activated(true);
}
else
{
// keep going
recognizeSpeechDirectly();
}
}
@Override
public void onError(int errorCode)
{
if ((errorCode == SpeechRecognizer.ERROR_NO_MATCH)
|| (errorCode == SpeechRecognizer.ERROR_SPEECH_TIMEOUT))
{
Log.d(TAG, "didn't recognize anything");
// keep going
recognizeSpeechDirectly();
}
else
{
Log.d(TAG,
"FAILED "
+ SpeechRecognitionUtil
.diagnoseErrorCode(errorCode));
}
}
/**
* lazy initialize the speech recognizer
*/
private SpeechRecognizer getSpeechRecognizer()
{
if (recognizer == null)
{
recognizer = SpeechRecognizer.createSpeechRecognizer(context);
}
return recognizer;
}
// other unused methods from RecognitionListener...
@Override
public void onReadyForSpeech(Bundle params)
{
Log.d(TAG, "ready for speech " + params);
}
@Override
public void onEndOfSpeech()
{
}
/**
* @see android.speech.RecognitionListener#onBeginningOfSpeech()
*/
@Override
public void onBeginningOfSpeech()
{
}
@Override
public void onBufferReceived(byte[] buffer)
{
}
@Override
public void onRmsChanged(float rmsdB)
{
}
@Override
public void onEvent(int eventType, Bundle params)
{
}
}