Created
January 25, 2013 10:40
-
-
Save shaobin0604/4633430 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.android.soundrecorder; | |
| import android.content.Context; | |
| import android.content.res.Resources; | |
| import android.graphics.Canvas; | |
| import android.graphics.Paint; | |
| import android.graphics.drawable.Drawable; | |
| import android.util.AttributeSet; | |
| import android.util.Log; | |
| import android.view.View; | |
| import java.util.Random; | |
| public class VUMeter extends View { | |
| static final float PIVOT_RADIUS = 3.5f; | |
| static final float PIVOT_Y_OFFSET = 10f; | |
| static final float SHADOW_OFFSET = 2.0f; | |
| static final float DROPOFF_STEP = 0.18f; | |
| static final float SURGE_STEP = 0.35f; | |
| static final long ANIMATION_INTERVAL = 70; | |
| private final int HY = 32768; | |
| private final int PART1 = HY / 28; | |
| private final int PART2 = PART1 * 3; | |
| private final int PART3 = PART1 * 6; | |
| private final int PART4 = PART1 * 10; | |
| private final int PART5 = PART1 * 15; | |
| private final int PART6 = PART1 * 21; | |
| private final int PART7 = PART1 * 28; | |
| public static final float FLG_X = 0, FLG_Y = 0; | |
| Paint mPaint; | |
| Recorder mRecorder; | |
| private final int[] VOICE_ON = { R.drawable.voice_off, R.drawable.voice1_on, R.drawable.voice2_on, | |
| R.drawable.voice3_on, R.drawable.voice4_on, R.drawable.voice5_on, R.drawable.voice6_on, | |
| R.drawable.voice7_on }; | |
| private VoiceImageBean[] imageBean; | |
| private boolean isFirstLoadFlg = true; | |
| //------- | |
| private Drawable[] mTiles = new Drawable[5]; | |
| private int[] mTileColors = new int[5]; | |
| private static final int ROW_COUNT = 10; | |
| private static final int COL_COUNT = 24; | |
| private int[] mLevels = new int[COL_COUNT]; | |
| private static final int PADDING = 1; | |
| private Random mRandom = new Random(System.currentTimeMillis()); | |
| //------- | |
| public VUMeter(Context context) { | |
| super(context); | |
| init(context); | |
| } | |
| public VUMeter(Context context, AttributeSet attrs) { | |
| super(context, attrs); | |
| init(context); | |
| } | |
| void init(Context context) { | |
| mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
| mRecorder = null; | |
| imageBean = new VoiceImageBean[9]; | |
| Resources resources = context.getResources(); | |
| mTiles[0] = resources.getDrawable(R.drawable.spectrum_level_0); | |
| mTiles[1] = resources.getDrawable(R.drawable.spectrum_level_1); | |
| mTiles[2] = resources.getDrawable(R.drawable.spectrum_level_2); | |
| mTiles[3] = resources.getDrawable(R.drawable.spectrum_level_3); | |
| mTiles[4] = resources.getDrawable(R.drawable.spectrum_level_4); | |
| mTileColors[0] = resources.getColor(R.color.spectrum_level_0); | |
| mTileColors[1] = resources.getColor(R.color.spectrum_level_1); | |
| mTileColors[2] = resources.getColor(R.color.spectrum_level_2); | |
| mTileColors[3] = resources.getColor(R.color.spectrum_level_3); | |
| mTileColors[4] = resources.getColor(R.color.spectrum_level_4); | |
| } | |
| public void setRecorder(Recorder recorder) { | |
| mRecorder = recorder; | |
| invalidate(); | |
| } | |
| @Override | |
| protected void onDraw(Canvas canvas) { | |
| super.onDraw(canvas); | |
| if (isFirstLoadFlg) { | |
| initVoiceImage(); | |
| isFirstLoadFlg = false; | |
| } else { | |
| resetVoiceImage(); | |
| } | |
| // for (VoiceImageBean bean : imageBean) { | |
| // canvas.drawBitmap(bean.getBitmap(), bean.getX(), bean.getY(), null); | |
| // } | |
| drawHist(canvas); | |
| if (mRecorder != null && mRecorder.state() == Recorder.RECORDING_STATE) | |
| // postInvalidateDelayed(ANIMATION_INTERVAL); | |
| postInvalidate(); | |
| } | |
| private void initVoiceImage() { | |
| int width = getWidth(); | |
| for (int i = 0; i < imageBean.length; i++) { | |
| VoiceImageBean bean = new VoiceImageBean(getContext()); | |
| bean.setBitmap(R.drawable.voice_off); | |
| if (width != 0) { | |
| bean.setX(FLG_X + 26 * width / 243 * (i)); | |
| } else { | |
| bean.setX(FLG_X + 26 * (i)); | |
| } | |
| bean.setY(FLG_Y); | |
| imageBean[i] = bean; | |
| } | |
| } | |
| private static final String TAG = VUMeter.class.getSimpleName(); | |
| private void drawHist(Canvas canvas) { | |
| updateLevels(); | |
| int width = getWidth(); | |
| int height = getHeight(); | |
| Log.d(TAG, "width = " + width + ", height = " + height); | |
| int tileWidth = width / COL_COUNT; | |
| int tileHeight = height / ROW_COUNT; | |
| Log.d(TAG, "tileWidth = " + tileWidth + ", tileHeight = " + tileHeight); | |
| int startX = 0; | |
| int startY = 0; | |
| int left = startX; | |
| int top = startY; | |
| int right; | |
| int bottom; | |
| for (int i = 0; i < COL_COUNT; i++) { | |
| int level = mLevels[i]; | |
| right = left + tileWidth; | |
| top = startY; | |
| final int offset = ROW_COUNT - level; | |
| for (int j = 0, k = 0, l = 4; j < ROW_COUNT; j++) { | |
| bottom = top + tileHeight; | |
| int color; | |
| if (k < offset) { | |
| color = mTileColors[0]; | |
| k++; | |
| } else { | |
| color = mTileColors[l]; | |
| l = l - 1; | |
| if (l < 0) { | |
| l = 0; | |
| } | |
| } | |
| mPaint.setColor(color); | |
| canvas.drawRect(left + PADDING, top + PADDING, right - PADDING, bottom - PADDING, mPaint); | |
| top += tileHeight; | |
| level -= 1; | |
| } | |
| left += tileWidth; | |
| } | |
| } | |
| private void updateLevels() { | |
| for (int i = 0; i < mLevels.length; i++) { | |
| mLevels[i] = mRandom.nextInt(ROW_COUNT + 1); | |
| } | |
| } | |
| private void resetVoiceImage() { | |
| int level = getLevel(mRecorder.getMaxAmplitude()); | |
| if (level > 0) { | |
| level = level - 1 < 0 ? 0 : level - 1; | |
| int rank1 = level;// 7 | |
| int rank2 = level - 1 >= 0 ? level - 1 : 0;// 6 | |
| int rank3 = level - 2 >= 0 ? level - 2 : 0;// 5 | |
| int rank4 = level - 3 >= 0 ? level - 3 : 0;// 4 | |
| int rank5 = level - 4 >= 0 ? level - 4 : 0;// 3 | |
| int rank6 = level - 5 >= 0 ? level - 5 : 0;// 2 | |
| int rank7 = level - 6 >= 0 ? level - 6 : 0;// 1 | |
| imageBean[0].setBitmap(VOICE_ON[rank6]); | |
| imageBean[1].setBitmap(VOICE_ON[rank5]); | |
| imageBean[2].setBitmap(VOICE_ON[rank6]); | |
| imageBean[3].setBitmap(VOICE_ON[rank3]); | |
| imageBean[4].setBitmap(VOICE_ON[rank1]); | |
| imageBean[5].setBitmap(VOICE_ON[rank2]); | |
| imageBean[6].setBitmap(VOICE_ON[rank4]); | |
| imageBean[7].setBitmap(VOICE_ON[rank5]); | |
| imageBean[8].setBitmap(VOICE_ON[rank7]); | |
| } | |
| } | |
| private int getLevel(int value) { | |
| int level = 0; | |
| if (value == 0) | |
| return level; | |
| if (value <= PART1) | |
| level = 1; | |
| else if (value <= PART2) | |
| level = 2; | |
| else if (value <= PART3) | |
| level = 3; | |
| else if (value <= PART4) | |
| level = 4; | |
| else if (value <= PART5) | |
| level = 5; | |
| else if (value <= PART6) | |
| level = 6; | |
| else if (value <= PART7) | |
| level = 7; | |
| else | |
| level = 8; | |
| return level; | |
| } | |
| @Override | |
| public void setVisibility(int visibility) { | |
| if (View.VISIBLE == visibility) { | |
| initVoiceImage(); | |
| } | |
| super.setVisibility(visibility); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment