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