Androidで音声認識
最近はSiriさんとかが流行ってるようなので、Androidの音声認識を試してみた。
Androidの音声認識は、googleのサーバー側で提供される音声検索機能を使用して
実現される。なので、3GでもWifiでもいいのでネットワークに接続されている必要が
あります。
一番シンプルなのは、RecognizerIntentを使用する形。
doc: http://developer.android.com/reference/android/speech/RecognizerIntent.html
サンプルソースとかは適当にググればいっぱい出てくるので割愛。
ただし、これは組み込み済の音声認識ダイアログが表示されるものなので、UI的に自由が効かない。
そこで、バックグラウンドで音声認識を行なってくれるSpeechRecognizerを使用してみた。
doc: http://developer.android.com/reference/android/speech/SpeechRecognizer.html
以下に実装例を示す。
起動するとひたすら音声認識を待ち受け続ける。
やっつけ仕事なので、あまり参考にしないように注意。
※そもそも実装の仕方間違ってると思う。
あと、前述のとおり音声認識はサーバーとの通信が発生するので、起動しているだけで
笑えるくらいバンバン通信します。Wifi推奨。
つうかスタンドアローンで動かしたいね。別にややこしい言葉とか認識しなくていいから。
どっかにAPIころがってないかな。
[サンプルソース]
package net.omu;
import java.util.ArrayList;
import android.app.Activity;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.Vibrator;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.widget.Toast;
public class SampleVoiceMemoActivity extends Activity {
SpeechRecognizer mSpeechRec;
SampleRecognitionListener mRecogListener = new SampleRecognitionListener();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
// 音声認識開始
mSpeechRec = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
mSpeechRec.setRecognitionListener(mRecogListener);
mSpeechRec.startListening(RecognizerIntent
.getVoiceDetailsIntent(getApplicationContext()));
}
@Override
protected void onStop() {
super.onStop();
mSpeechRec.destroy();
}
public class SampleRecognitionListener implements RecognitionListener {
@Override
public void onResults(Bundle results) {
// 音声検索結果
ArrayList<String> reslurtWordList = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
// 候補の一つ目を表示
String resultWord = reslurtWordList.get(0);
Toast.makeText(getApplicationContext(), resultWord,
Toast.LENGTH_SHORT).show();
// 名前を呼ばれると返事する
if ("ダッフィー".equals(resultWord)) {
ToneGenerator toneGenerator = new ToneGenerator(
AudioManager.STREAM_SYSTEM, ToneGenerator.MAX_VOLUME);
toneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP);
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(1000);
}
// 再度音声認識開始
mSpeechRec.setRecognitionListener(mRecogListener);
mSpeechRec.startListening(RecognizerIntent
.getVoiceDetailsIntent(getApplicationContext()));
}
@Override
public void onError(int error) {
// 再度音声認識開始 ※候補が見つからない時とかにここが呼ばれるっぽい
mSpeechRec.setRecognitionListener(mRecogListener);
mSpeechRec.startListening(RecognizerIntent
.getVoiceDetailsIntent(getApplicationContext()));
}
<<省略>>
}
}
【まとめ】
通信必須なのでバッテリーとかの面でもひたすら待受続けるのはいけてないっぽい。
ディズニー行きたい。ミッキーさんに会いたい。ダッフィーモフモフしたい。