1f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch/*
2f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Copyright (C) 2011 The Android Open Source Project
3f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
4f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Licensed under the Apache License, Version 2.0 (the "License");
5f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * you may not use this file except in compliance with the License.
6f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * You may obtain a copy of the License at
7f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
8f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *      http://www.apache.org/licenses/LICENSE-2.0
9f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch *
10f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * Unless required by applicable law or agreed to in writing, software
11f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * distributed under the License is distributed on an "AS IS" BASIS,
12f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * See the License for the specific language governing permissions and
14f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch * limitations under the License.
15f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch */
16f2ef799d0826b6d4f9bb3727f7878545b3ad29b9Ben Murdoch
1745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectpackage com.android.soundrecorder;
1845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
1945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport java.util.Map;
2045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
2145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.content.Context;
2245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.graphics.Canvas;
2345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.graphics.Color;
2445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.graphics.Paint;
2545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.graphics.drawable.Drawable;
2645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.util.AttributeSet;
2745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectimport android.view.View;
2845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
2945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Projectpublic class VUMeter extends View {
3045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final float PIVOT_RADIUS = 3.5f;
3145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final float PIVOT_Y_OFFSET = 10f;
3245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final float SHADOW_OFFSET = 2.0f;
3345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final float DROPOFF_STEP = 0.18f;
3445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final float SURGE_STEP = 0.35f;
3545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    static final long  ANIMATION_INTERVAL = 70;
3645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
3745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    Paint mPaint, mShadow;
3845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    float mCurrentAngle;
3945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    Recorder mRecorder;
4145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public VUMeter(Context context) {
4345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        super(context);
4445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        init(context);
4545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
4645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
4745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public VUMeter(Context context, AttributeSet attrs) {
4845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        super(context, attrs);
4945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        init(context);
5045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
5145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
5245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    void init(Context context) {
5345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        Drawable background = context.getResources().getDrawable(R.drawable.vumeter);
5445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        setBackgroundDrawable(background);
5545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
5645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
5745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mPaint.setColor(Color.WHITE);
5845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
5945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mShadow.setColor(Color.argb(60, 0, 0, 0));
6045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mRecorder = null;
6245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mCurrentAngle = 0;
6445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
6545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
6645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    public void setRecorder(Recorder recorder) {
6745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    	mRecorder = recorder;
6845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    	invalidate();
6945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
7045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
7145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    @Override
7245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    protected void onDraw(Canvas canvas) {
7345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        super.onDraw(canvas);
7445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
7545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        final float minAngle = (float)Math.PI/8;
7645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        final float maxAngle = (float)Math.PI*7/8;
7745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
7845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float angle = minAngle;
7945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mRecorder != null)
8045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        	angle += (float)(maxAngle - minAngle)*mRecorder.getMaxAmplitude()/32768;
8145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
8245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (angle > mCurrentAngle)
8345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mCurrentAngle = angle;
8445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        else
8545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project            mCurrentAngle = Math.max(angle, mCurrentAngle - DROPOFF_STEP);
8645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
8745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        mCurrentAngle = Math.min(maxAngle, mCurrentAngle);
8845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
8945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float w = getWidth();
9045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float h = getHeight();
9145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float pivotX = w/2;
9245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float pivotY = h - PIVOT_RADIUS - PIVOT_Y_OFFSET;
9345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float l = h*4/5;
9445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float sin = (float) Math.sin(mCurrentAngle);
9545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float cos = (float) Math.cos(mCurrentAngle);
9645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float x0 = pivotX - l*cos;
9745fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        float y0 = pivotY - l*sin;
9845fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        canvas.drawLine(x0 + SHADOW_OFFSET, y0 + SHADOW_OFFSET, pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, mShadow);
9945fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        canvas.drawCircle(pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, PIVOT_RADIUS, mShadow);
10045fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        canvas.drawLine(x0, y0, pivotX, pivotY, mPaint);
10145fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        canvas.drawCircle(pivotX, pivotY, PIVOT_RADIUS, mPaint);
10245fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project
10345fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        if (mRecorder != null && mRecorder.state() == Recorder.RECORDING_STATE)
10445fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project        	postInvalidateDelayed(ANIMATION_INTERVAL);
10545fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project    }
10645fd319136b87911aae50269618b51c4a5902ad9The Android Open Source Project}
107