package com.todoroo.aacenc;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
@TargetApi(8)
public class RecognizerApi implements RecognitionListener {
public static interface PlaybackExceptionHandler {
public void playbackFailed(String file);
}
private String aacFile;
private Context context;
public static interface RecognizerApiListener {
public void onSpeechResult(String result);
public void onSpeechError(int error);
}
private RecognizerApiListener mListener;
public RecognizerApi(Context context) {
this.context = context;
File dir = context.getFilesDir();
aacFile = dir.toString() + "/audio.aac";
sr = SpeechRecognizer.createSpeechRecognizer(context);
}
public void setTemporaryFile(String fileName) {
aacFile = context.getFilesDir().toString() + "/" + fileName;
}
public String getTemporaryFile() {
return aacFile;
}
public void setListener(RecognizerApiListener listener) {
this.mListener = listener;
}
public static void play(Activity activity, String file, PlaybackExceptionHandler handler) {
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(file);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
handler.playbackFailed(file);
}
}
private AACEncoder encoder = new AACEncoder();
private long speechStarted = 0;
private SpeechRecognizer sr;
private ProgressDialog speakPd;
private ProgressDialog processingPd;
private String processingMessage;
/**
* Start speech recognition
*
* @param callingPackage e.g. com.myapp.example
* @param speakNowMessage e.g. "Speak now!"
* @param processingMessage e.g. "Processing..."
*/
public void start(String callingPackage, String speakNowMessage, String processingMessage) {
sr.setRecognitionListener(this);
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, callingPackage);
speechStarted = 0;
baos.reset();
speakPd = new ProgressDialog(context);
speakPd.setMessage(speakNowMessage);
speakPd.setIndeterminate(true);
speakPd.setCancelable(true);
speakPd.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
sr.cancel();
onEndOfSpeech();
}
});
speakPd.show();
sr.startListening(intent);
speechStarted = System.currentTimeMillis();
}
/**
* Convert AAC file to M4A
*
* @param toFile
* @throws IOException
*/
public void convert(String toFile) throws IOException {
new AACToM4A().convert(context, aacFile, toFile);
}
public void cancel() {
sr.cancel();
}
public void destroy() {
sr.setRecognitionListener(null);
sr.destroy();
}
// --- RecognitionListener methods --- //
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Override
public void onBeginningOfSpeech() {
}
@Override
public void onBufferReceived(byte[] buffer) {
if(speechStarted > 0) {
try {
baos.write(buffer);
} catch (IOException e) {
//
}
}
}
@Override
public void onEndOfSpeech() {
speakPd.dismiss();
if(speechStarted == 0)
return;
processingPd = new ProgressDialog(context);
processingPd.setMessage(processingMessage);
processingPd.setIndeterminate(true);
processingPd.setCancelable(true);
processingPd.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
sr.cancel();
}
});
processingPd.show();
long delta = System.currentTimeMillis() - speechStarted;
int sampleRate = (int) (baos.size() * 1000 / delta);
sampleRate = 8000; // THIS IS A MAGIC NUMBER@?!!?!?!
// can i has calculate?
encoder.init(64000, 1, sampleRate, 16, aacFile);
encoder.encode(baos.toByteArray());
encoder.uninit();
}
@Override
public void onError(int error) {
if (mListener != null)
mListener.onSpeechError(error);
Log.w("Speech Error", "Error code: " + error);
}
@Override
public void onEvent(int arg0, Bundle arg1) {
//
}
@Override
public void onPartialResults(Bundle partialResults) {
onResults(partialResults);
}
@Override
public void onReadyForSpeech(Bundle arg0) {
}
@Override
public void onResults(Bundle results) {
processingPd.dismiss();
ArrayList<String> strings = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (mListener != null)
mListener.onSpeechResult(strings.size() == 0 ? "" : strings.get(0));
}
@Override
public void onRmsChanged(float arg0) {
}
}