package cn.qylk.myview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
public class VisualizerView extends View {
private static final int mSpectrumNum = 32;
private int baseX;
private int height, width;
private byte[] mBytes = new byte[mSpectrumNum];
private Paint mForePaint = new Paint();
private float[] mPoints = new float[mSpectrumNum * 4];
private Paint poPaint = new Paint();
private float scalefit;
private float[] toppoint = new float[mSpectrumNum];
private int xplot[] = new int[mSpectrumNum + 1];
public VisualizerView(Context context) {
this(context, null);
}
public VisualizerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VisualizerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public void ClearView() {
for (int i = 0; i < mSpectrumNum; i++) {
mBytes[i] = 0;
toppoint[i] = height;
}
invalidate();
}
private void init() {
poPaint.setStrokeWidth(2f);
poPaint.setColor(0xFFFFFF00);
mForePaint.setColor(0xFFFFFFFF);
mForePaint.setStyle(Style.STROKE);
mForePaint.setStrokeWidth(12f);
for (int i = 0; i <= mSpectrumNum; i++) {
xplot[i] = 0;
xplot[i] = (int) (0.5 + Math.pow(63, (double) i / mSpectrumNum));
if (i > 0 && xplot[i] <= xplot[i - 1])
xplot[i] = xplot[i - 1] + 1;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < mSpectrumNum; i++) {
final int xi = baseX * i + baseX / 2;
mPoints[i * 4] = xi;
mPoints[i * 4 + 1] = height;
mPoints[i * 4 + 2] = xi;
mPoints[i * 4 + 3] = height - mBytes[i] + 3;
if (mPoints[i * 4 + 3] < toppoint[i])
toppoint[i] = mPoints[i * 4 + 3];
else
toppoint[i] += 4;
if (toppoint[i] > height - 4)
toppoint[i] = height - 4;
canvas.drawRect(xi - 6, toppoint[i], xi + 6, toppoint[i] + 2,
poPaint);
}
canvas.drawLines(mPoints, mForePaint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
height = h;
width = w;
baseX = width / mSpectrumNum;
scalefit = 128.0f / height;
for (int i = 0; i < toppoint.length; i++) {
toppoint[i] = height - 4;
}
super.onSizeChanged(w, h, oldw, oldh);
}
public void setUpView() {
setVisibility(View.VISIBLE);
}
private void getModule(byte[] fft) {
int len = fft.length;
double t;
for (int i = 0, j = 0; i < len; i++, j++) {
t = Math.hypot(fft[i], fft[i + 1]);
if (t > 127)
fft[j] = (byte) 127;
else
fft[j] = (byte) t;
i++;
}
}
public void updateVisualizer(byte[] fft) {
getModule(fft);
// FFT数据详见public int getFft (byte[] fft)方法解释;
// 以下做了非标准FFT显示处理.只是为了达到较佳的显示效果
int xi, y;
for (int i = 0; i < mSpectrumNum; i++) {
mBytes[i] = 0;
for (xi = xplot[i], y = xplot[i + 1]; xi < y; xi++) {
if (fft[xi] > mBytes[i])
mBytes[i] = fft[xi];
}
mBytes[i] = (byte) (mBytes[i] / scalefit);
}
invalidate();
}
}