Skip to content

Instantly share code, notes, and snippets.

@shaobin0604
Created January 25, 2013 10:40
Show Gist options
  • Select an option

  • Save shaobin0604/4633430 to your computer and use it in GitHub Desktop.

Select an option

Save shaobin0604/4633430 to your computer and use it in GitHub Desktop.
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