• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.inputmethod.deprecated.voice;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Bitmap.Config;
22 import android.graphics.Canvas;
23 import android.graphics.Paint;
24 import android.graphics.PorterDuff;
25 import android.graphics.PorterDuffXfermode;
26 import android.graphics.Rect;
27 import android.graphics.drawable.BitmapDrawable;
28 import android.graphics.drawable.Drawable;
29 import android.os.Handler;
30 import android.util.AttributeSet;
31 import android.widget.ImageView;
32 
33 import com.android.inputmethod.latin.R;
34 
35 /**
36  * A widget which shows the volume of audio using a microphone icon
37  */
38 public class SoundIndicator extends ImageView {
39     @SuppressWarnings("unused")
40     private static final String TAG = "SoundIndicator";
41 
42     private static final float UP_SMOOTHING_FACTOR = 0.9f;
43     private static final float DOWN_SMOOTHING_FACTOR = 0.4f;
44 
45     private static final float AUDIO_METER_MIN_DB = 7.0f;
46     private static final float AUDIO_METER_DB_RANGE = 20.0f;
47 
48     private static final long FRAME_DELAY = 50;
49 
50     private Bitmap mDrawingBuffer;
51     private Canvas mBufferCanvas;
52     private Bitmap mEdgeBitmap;
53     private float mLevel = 0.0f;
54     private Drawable mFrontDrawable;
55     private Paint mClearPaint;
56     private Paint mMultPaint;
57     private int mEdgeBitmapOffset;
58 
59     private Handler mHandler;
60 
61     private Runnable mDrawFrame = new Runnable() {
62         public void run() {
63             invalidate();
64             mHandler.postDelayed(mDrawFrame, FRAME_DELAY);
65         }
66     };
67 
SoundIndicator(Context context)68     public SoundIndicator(Context context) {
69         this(context, null);
70     }
71 
SoundIndicator(Context context, AttributeSet attrs)72     public SoundIndicator(Context context, AttributeSet attrs) {
73         super(context, attrs);
74 
75         mFrontDrawable = getDrawable();
76         BitmapDrawable edgeDrawable =
77                 (BitmapDrawable) context.getResources().getDrawable(R.drawable.vs_popup_mic_edge);
78         mEdgeBitmap = edgeDrawable.getBitmap();
79         mEdgeBitmapOffset = mEdgeBitmap.getHeight() / 2;
80 
81         mDrawingBuffer =
82                 Bitmap.createBitmap(mFrontDrawable.getIntrinsicWidth(),
83                         mFrontDrawable.getIntrinsicHeight(), Config.ARGB_8888);
84 
85         mBufferCanvas = new Canvas(mDrawingBuffer);
86 
87         // Initialize Paints.
88         mClearPaint = new Paint();
89         mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
90 
91         mMultPaint = new Paint();
92         mMultPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
93 
94         mHandler = new Handler();
95     }
96 
97     @Override
onDraw(Canvas canvas)98     public void onDraw(Canvas canvas) {
99         //super.onDraw(canvas);
100 
101         float w = getWidth();
102         float h = getHeight();
103 
104         // Clear the buffer canvas
105         mBufferCanvas.drawRect(0, 0, w, h, mClearPaint);
106 
107         // Set its clip so we don't draw the front image all the way to the top
108         Rect clip = new Rect(0,
109                 (int) ((1.0 - mLevel) * (h + mEdgeBitmapOffset)) - mEdgeBitmapOffset,
110                 (int) w,
111                 (int) h);
112 
113         mBufferCanvas.save();
114         mBufferCanvas.clipRect(clip);
115 
116         // Draw the front image
117         mFrontDrawable.setBounds(new Rect(0, 0, (int) w, (int) h));
118         mFrontDrawable.draw(mBufferCanvas);
119 
120         mBufferCanvas.restore();
121 
122         // Draw the edge image on top of the buffer image with a multiply mode
123         mBufferCanvas.drawBitmap(mEdgeBitmap, 0, clip.top, mMultPaint);
124 
125         // Draw the buffer image (on top of the background image)
126         canvas.drawBitmap(mDrawingBuffer, 0, 0, null);
127     }
128 
129     /**
130      * Sets the sound level
131      *
132      * @param rmsdB The level of the sound, in dB.
133      */
setRmsdB(float rmsdB)134     public void setRmsdB(float rmsdB) {
135         float level = ((rmsdB - AUDIO_METER_MIN_DB) / AUDIO_METER_DB_RANGE);
136 
137         level = Math.min(Math.max(0.0f, level), 1.0f);
138 
139         // We smooth towards the new level
140         if (level > mLevel) {
141             mLevel = (level - mLevel) * UP_SMOOTHING_FACTOR + mLevel;
142         } else {
143             mLevel = (level - mLevel) * DOWN_SMOOTHING_FACTOR + mLevel;
144         }
145         invalidate();
146     }
147 
start()148     public void start() {
149         mHandler.post(mDrawFrame);
150     }
151 
stop()152     public void stop() {
153         mHandler.removeCallbacks(mDrawFrame);
154     }
155 }
156