オムレツ工房

androidとかiPhoneとかの開発雑記

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()));
		}

		<<省略>>
		
	}
}

【まとめ】

通信必須なのでバッテリーとかの面でもひたすら待受続けるのはいけてないっぽい。
ディズニー行きたい。ミッキーさんに会いたい。ダッフィーモフモフしたい。