1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of 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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.soundrecorder;
18 
19 import java.util.Map;
20 
21 import android.content.Context;
22 import android.graphics.Canvas;
23 import android.graphics.Color;
24 import android.graphics.Paint;
25 import android.graphics.drawable.Drawable;
26 import android.util.AttributeSet;
27 import android.view.View;
28 
29 public class VUMeter extends View {
30     static final float PIVOT_RADIUS = 3.5f;
31     static final float PIVOT_Y_OFFSET = 10f;
32     static final float SHADOW_OFFSET = 2.0f;
33     static final float DROPOFF_STEP = 0.18f;
34     static final float SURGE_STEP = 0.35f;
35     static final long  ANIMATION_INTERVAL = 70;
36 
37     Paint mPaint, mShadow;
38     float mCurrentAngle;
39 
40     Recorder mRecorder;
41 
VUMeter(Context context)42     public VUMeter(Context context) {
43         super(context);
44         init(context);
45     }
46 
VUMeter(Context context, AttributeSet attrs)47     public VUMeter(Context context, AttributeSet attrs) {
48         super(context, attrs);
49         init(context);
50     }
51 
init(Context context)52     void init(Context context) {
53         Drawable background = context.getResources().getDrawable(R.drawable.vumeter);
54         setBackgroundDrawable(background);
55 
56         mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
57         mPaint.setColor(Color.WHITE);
58         mShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
59         mShadow.setColor(Color.argb(60, 0, 0, 0));
60 
61         mRecorder = null;
62 
63         mCurrentAngle = 0;
64     }
65 
setRecorder(Recorder recorder)66     public void setRecorder(Recorder recorder) {
67     	mRecorder = recorder;
68     	invalidate();
69     }
70 
71     @Override
onDraw(Canvas canvas)72     protected void onDraw(Canvas canvas) {
73         super.onDraw(canvas);
74 
75         final float minAngle = (float)Math.PI/8;
76         final float maxAngle = (float)Math.PI*7/8;
77 
78         float angle = minAngle;
79         if (mRecorder != null)
80         	angle += (float)(maxAngle - minAngle)*mRecorder.getMaxAmplitude()/32768;
81 
82         if (angle > mCurrentAngle)
83             mCurrentAngle = angle;
84         else
85             mCurrentAngle = Math.max(angle, mCurrentAngle - DROPOFF_STEP);
86 
87         mCurrentAngle = Math.min(maxAngle, mCurrentAngle);
88 
89         float w = getWidth();
90         float h = getHeight();
91         float pivotX = w/2;
92         float pivotY = h - PIVOT_RADIUS - PIVOT_Y_OFFSET;
93         float l = h*4/5;
94         float sin = (float) Math.sin(mCurrentAngle);
95         float cos = (float) Math.cos(mCurrentAngle);
96         float x0 = pivotX - l*cos;
97         float y0 = pivotY - l*sin;
98         canvas.drawLine(x0 + SHADOW_OFFSET, y0 + SHADOW_OFFSET, pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, mShadow);
99         canvas.drawCircle(pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, PIVOT_RADIUS, mShadow);
100         canvas.drawLine(x0, y0, pivotX, pivotY, mPaint);
101         canvas.drawCircle(pivotX, pivotY, PIVOT_RADIUS, mPaint);
102 
103         if (mRecorder != null && mRecorder.state() == Recorder.RECORDING_STATE)
104         	postInvalidateDelayed(ANIMATION_INTERVAL);
105     }
106 }
107