diff options
Diffstat (limited to 'src/com/android/inputmethod/voice/RecognitionView.java')
-rw-r--r-- | src/com/android/inputmethod/voice/RecognitionView.java | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/src/com/android/inputmethod/voice/RecognitionView.java b/src/com/android/inputmethod/voice/RecognitionView.java deleted file mode 100644 index 1e99c3cf7..000000000 --- a/src/com/android/inputmethod/voice/RecognitionView.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. - * - * 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 com.android.inputmethod.voice; - -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; -import java.util.ArrayList; -import java.util.List; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.CornerPathEffect; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PathEffect; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.android.inputmethod.latin.R; - -/** - * The user interface for the "Speak now" and "working" states. - * Displays a recognition dialog (with waveform, voice meter, etc.), - * plays beeps, shows errors, etc. - */ -public class RecognitionView { - private static final String TAG = "RecognitionView"; - - private Handler mUiHandler; // Reference to UI thread - private View mView; - private Context mContext; - - private ImageView mImage; - private TextView mText; - private View mButton; - private TextView mButtonText; - private View mProgress; - - private Drawable mInitializing; - private Drawable mError; - private List<Drawable> mSpeakNow; - - private float mVolume = 0.0f; - private int mLevel = 0; - - private enum State {LISTENING, WORKING, READY} - private State mState = State.READY; - - private float mMinMicrophoneLevel; - private float mMaxMicrophoneLevel; - - /** Updates the microphone icon to show user their volume.*/ - private Runnable mUpdateVolumeRunnable = new Runnable() { - public void run() { - if (mState != State.LISTENING) { - return; - } - - final float min = mMinMicrophoneLevel; - final float max = mMaxMicrophoneLevel; - final int maxLevel = mSpeakNow.size() - 1; - - int index = (int) ((mVolume - min) / (max - min) * maxLevel); - final int level = Math.min(Math.max(0, index), maxLevel); - - if (level != mLevel) { - mImage.setImageDrawable(mSpeakNow.get(level)); - mLevel = level; - } - mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); - } - }; - - public RecognitionView(Context context, OnClickListener clickListener) { - mUiHandler = new Handler(); - - LayoutInflater inflater = (LayoutInflater) context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - mView = inflater.inflate(R.layout.recognition_status, null); - ContentResolver cr = context.getContentResolver(); - mMinMicrophoneLevel = SettingsUtil.getSettingsFloat( - cr, SettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f); - mMaxMicrophoneLevel = SettingsUtil.getSettingsFloat( - cr, SettingsUtil.LATIN_IME_MAX_MICROPHONE_LEVEL, 30.f); - - // Pre-load volume level images - Resources r = context.getResources(); - - mSpeakNow = new ArrayList<Drawable>(); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level0)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level1)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level2)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level3)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level4)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level5)); - mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level6)); - - mInitializing = r.getDrawable(R.drawable.mic_slash); - mError = r.getDrawable(R.drawable.caution); - - mImage = (ImageView) mView.findViewById(R.id.image); - mButton = mView.findViewById(R.id.button); - mButton.setOnClickListener(clickListener); - mText = (TextView) mView.findViewById(R.id.text); - mButtonText = (TextView) mView.findViewById(R.id.button_text); - mProgress = mView.findViewById(R.id.progress); - - mContext = context; - } - - public View getView() { - return mView; - } - - public void restoreState() { - mUiHandler.post(new Runnable() { - public void run() { - // Restart the spinner - if (mState == State.WORKING) { - ((ProgressBar)mProgress).setIndeterminate(false); - ((ProgressBar)mProgress).setIndeterminate(true); - } - } - }); - } - - public void showInitializing() { - mUiHandler.post(new Runnable() { - public void run() { - prepareDialog(false, mContext.getText(R.string.voice_initializing), mInitializing, - mContext.getText(R.string.cancel)); - } - }); - } - - public void showListening() { - mUiHandler.post(new Runnable() { - public void run() { - mState = State.LISTENING; - prepareDialog(false, mContext.getText(R.string.voice_listening), mSpeakNow.get(0), - mContext.getText(R.string.cancel)); - } - }); - mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); - } - - public void updateVoiceMeter(final float rmsdB) { - mVolume = rmsdB; - } - - public void showError(final String message) { - mUiHandler.post(new Runnable() { - public void run() { - mState = State.READY; - prepareDialog(false, message, mError, mContext.getText(R.string.ok)); - } - }); - } - - public void showWorking( - final ByteArrayOutputStream waveBuffer, - final int speechStartPosition, - final int speechEndPosition) { - - mUiHandler.post(new Runnable() { - public void run() { - mState = State.WORKING; - prepareDialog(true, mContext.getText(R.string.voice_working), null, mContext - .getText(R.string.cancel)); - final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()).order( - ByteOrder.nativeOrder()).asShortBuffer(); - buf.position(0); - waveBuffer.reset(); - showWave(buf, speechStartPosition / 2, speechEndPosition / 2); - } - }); - } - - private void prepareDialog(boolean spinVisible, CharSequence text, Drawable image, - CharSequence btnTxt) { - if (spinVisible) { - mProgress.setVisibility(View.VISIBLE); - mImage.setVisibility(View.GONE); - } else { - mProgress.setVisibility(View.GONE); - mImage.setImageDrawable(image); - mImage.setVisibility(View.VISIBLE); - } - mText.setText(text); - mButtonText.setText(btnTxt); - } - - /** - * @return an average abs of the specified buffer. - */ - private static int getAverageAbs(ShortBuffer buffer, int start, int i, int npw) { - int from = start + i * npw; - int end = from + npw; - int total = 0; - for (int x = from; x < end; x++) { - total += Math.abs(buffer.get(x)); - } - return total / npw; - } - - - /** - * Shows waveform of input audio. - * - * Copied from version in VoiceSearch's RecognitionActivity. - * - * TODO: adjust stroke width based on the size of data. - * TODO: use dip rather than pixels. - */ - private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) { - final int w = ((View) mImage.getParent()).getWidth(); - final int h = mImage.getHeight(); - if (w <= 0 || h <= 0) { - // view is not visible this time. Skip drawing. - return; - } - final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - final Canvas c = new Canvas(b); - final Paint paint = new Paint(); - paint.setColor(0xFFFFFFFF); // 0xAARRGGBB - paint.setAntiAlias(true); - paint.setStyle(Paint.Style.STROKE); - paint.setAlpha(0x90); - - final PathEffect effect = new CornerPathEffect(3); - paint.setPathEffect(effect); - - final int numSamples = waveBuffer.remaining(); - int endIndex; - if (endPosition == 0) { - endIndex = numSamples; - } else { - endIndex = Math.min(endPosition, numSamples); - } - - int startIndex = startPosition - 2000; // include 250ms before speech - if (startIndex < 0) { - startIndex = 0; - } - final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples - final float scale = 10.0f / 65536.0f; - - final int count = (endIndex - startIndex) / numSamplePerWave; - final float deltaX = 1.0f * w / count; - int yMax = h / 2 - 10; - Path path = new Path(); - c.translate(0, yMax); - float x = 0; - path.moveTo(x, 0); - yMax -= 10; - for (int i = 0; i < count; i++) { - final int avabs = getAverageAbs(waveBuffer, startIndex, i , numSamplePerWave); - int sign = ( (i & 01) == 0) ? -1 : 1; - final float y = Math.min(yMax, avabs * h * scale) * sign; - path.lineTo(x, y); - x += deltaX; - path.lineTo(x, y); - } - if (deltaX > 4) { - paint.setStrokeWidth(3); - } else { - paint.setStrokeWidth(Math.max(1, (int) (deltaX -.05))); - } - c.drawPath(path, paint); - mImage.setImageBitmap(b); - mImage.setVisibility(View.VISIBLE); - MarginLayoutParams mProgressParams = (MarginLayoutParams)mProgress.getLayoutParams(); - mProgressParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - -h / 2 - 18, mContext.getResources().getDisplayMetrics()); - - // Tweak the padding manually to fill out the whole view horizontally. - // TODO: Do this in the xml layout instead. - ((View) mImage.getParent()).setPadding(4, ((View) mImage.getParent()).getPaddingTop(), 3, - ((View) mImage.getParent()).getPaddingBottom()); - mProgress.setLayoutParams(mProgressParams); - } - - - public void finish() { - mUiHandler.post(new Runnable() { - public void run() { - mState = State.READY; - exitWorking(); - } - }); - } - - private void exitWorking() { - mProgress.setVisibility(View.GONE); - mImage.setVisibility(View.VISIBLE); - } -} |