Reputation: 221
My app uses Android's SpeechRecognizer class, and has been working fine on several devices until a couple days ago. On my Samsung S3 and my LG-E980 the app suddendly become very slow. My other devices are not affected. The problem occurs because there is about a 7 seconds wait between onBeginningOfSpeech and onEndOfSpeech. I have tried other apps with source code on the internet with the same result. Is anybody aware of any recent software change that may be causing this? My Samsung S3 is running Android 5.0.1 The Samsung that works well runs 4.1.2
The keyboard mic does not have delays.
Upvotes: 2
Views: 1403
Reputation: 221
I am pretty sure that this is slowdown is due to Google App (Google Search) version 6. I found this after testing 9 devices with the code below:
package com.example.speechtest;
import java.util.ArrayList;
import android.app.Activity;
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;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity implements RecognitionListener {
static String speechTestTag = "SpeechText";
MyView myView;
SpeechRecognizer speechRecognizer;
Intent speechIntent;
boolean processingSpeech = false;
long startTime;
long speechTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onCreate");
myView = new MyView(this);
setContentView(myView);
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
speechRecognizer.setRecognitionListener(this);
speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// speechIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 1100); // this line is ignored
// speechIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 0); // this line is ignored
}
class MyView extends LinearLayout {
TextView speechTimeView;
TextView textView;
Button talkButton;
public MyView(Context context) {
super(context);
setOrientation(LinearLayout.VERTICAL);
speechTimeView = new TextView(context);
speechTimeView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView = new TextView(context);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
talkButton = new Button(context);
talkButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
talkButton.setText("Touch to Talk");
talkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "talkButton calling startListening - processingSpeech = " + processingSpeech);
talkButton.setText("Speak");
speechTimeView.setText(" "); //speechTimeView.invalidate();
textView.setText(" "); //textView.invalidate();
speechRecognizer.startListening(speechIntent);
}
});
addView(speechTimeView);
addView(textView);
addView(talkButton);
}
}
@Override
public void onReadyForSpeech(Bundle params) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onReadyForSpeech");
processingSpeech = true;
}
@Override
public void onBeginningOfSpeech() {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onBeginningOfSpeech");
startTime = System.currentTimeMillis();
}
@Override
public void onRmsChanged(float rmsdB) {
//// if(BuildConfig.DEBUG) Log.d(speechTestTag, "onRmsChanged - new rmssB = " + rmsdB); // too much of this on some devices
}
@Override
public void onBufferReceived(byte[] buffer) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onBufferReceived");
}
@Override
public void onEndOfSpeech() {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onEndOfSpeech");
long endTime = System.currentTimeMillis();
speechTime = endTime - startTime;
myView.speechTimeView.setText("SpeechTime: " + speechTime + " Milliseconds");
}
@Override
public void onError(int error) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onError error: " + error + " processingSpeech = " + processingSpeech + " speechTime = " + speechTime);
if(error == 7 && (!processingSpeech || speechTime < 1700)) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onError startListening");
speechRecognizer.startListening(speechIntent);
} else {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onError displaying error");
myView.textView.setText("< " + "ERROR " + error + " >");
myView.talkButton.setText("Touch to Talk");
}
processingSpeech = false;
}
@Override
public void onResults(Bundle results) {
ArrayList<String> recognitionResults = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
String myResult = recognitionResults.get(0);
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onResults - <" + myResult + ">");
myView.textView.setText(myResult);
myView.talkButton.setText("Touch to Talk");
processingSpeech = false;
}
@Override
public void onPartialResults(Bundle partialResults) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onPartialResults");
}
@Override
public void onEvent(int eventType, Bundle params) {
if(BuildConfig.DEBUG) Log.d(speechTestTag, "onEvent");
}
}
This code is self contained, it does not need any XML layouts.
Do not forget to add
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
to your manifest.
Also, version 3 of Google App supports off line speech recognition. Version 4 does not. I have not version 5 to be able to tell. Version 6.0.23.21 does support off-line, but it is very slow. The problem is the time it takes from onBeginningOfSpeech to onEndOfSpeech. After the speech stops it keeps waiting for about 5 seconds before deciding that there will be no more speech and proceed with the recognition (both on and off line).The EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS parameter is ignored even if you make it zero or negative.
Three of my phones had Google App version 6, but I was able to revert to a previous version on all of them and the problem went away.
There is another problem with ERROR 7, which I solved with the boolean flag processingSpeech.
Upvotes: 3