android 音乐频谱
2014-01-15 18:54
483 查看
public class VisualizerView extends View { // 取得有效数据 int length = 512; // 线条数(必须为数据的1/4以下) int index = 128; // 下落速度 int downspeed = 24; private byte[] mBytes; private float[] mPoints;// 当前位置 private float[] mPoints2; // 上一次位置 private float[] upsetPoints;// 倒影 private Paint mForePaint = new Paint(); private Paint upsetPaint = new Paint();// 倒影 public VisualizerView(Context context){ super(context); init(); } public VisualizerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { LinearGradient mRadialGradient = new LinearGradient(0, 0, 0, 400,new int[] { Color.WHITE, Color.rgb(0, 128, 255) }, null,Shader.TileMode.MIRROR); mBytes = null; mForePaint.setStrokeWidth(2f); mForePaint.setAntiAlias(true); mForePaint.setShader(mRadialGradient); upsetPaint.setStrokeWidth(2f); upsetPaint.setAntiAlias(true); upsetPaint.setShader(mRadialGradient); upsetPaint.setAlpha(150); } public void updateVisualizer(byte[] bytes) { mBytes = bytes; invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mBytes == null || mBytes.length < 3) { return; } byte[] model1 = new byte[length / 2 + 1]; model1[0] = (byte) Math.abs(mBytes[1]); int j = 1; for (int i = 2; i < length/4;) { model1[j] = (byte) Math.hypot(mBytes[i], mBytes[i + 1]); i += 2; j++; } byte[] model = new byte[length / 2 + 1]; model[0] = (byte) Math.abs(model1[1]); j = 1; for (int i = 2; i < length / 2;) { model[j] = (byte) Math.max(model1[i], model1[i + 1]); if (j > 0) { model[j] = (byte) ((model[j] + model[j - 1]) / 2); } i += 2; j++; } // 需要画出线条的坐标系 if (mPoints == null || mPoints.length < index * 4) { mPoints = new float[index * 4]; upsetPoints = new float[index * 4]; mPoints2 = new float[index * 4]; } for (int i = 0; i < index; i++) { if (model[i] < 0) { model[i] = 127; } if (model[i] > 127) { model[i] = 127; } float zoom = (float) (14.5 * i / index + 2.5); if (model[i] < 5) { zoom = 4; } mPoints[i * 4] = getWidth() * i / index; mPoints[i * 4 + 1] = getHeight() / 3 * 2; mPoints[i * 4 + 2] = getWidth() * i / index; mPoints[i * 4 + 3] = 1 + getHeight() / 3 * 2 - model[i] * zoom; upsetPoints[i * 4] = mPoints[i * 4]; upsetPoints[i * 4 + 1] = mPoints[i * 4 + 1] + 4; upsetPoints[i * 4 + 2] = mPoints[i * 4 + 2]; upsetPoints[i * 4 + 3] = mPoints[i * 4 + 3] + model[i] * zoom * 3 / 2; mPoints2[i * 4] = mPoints[i * 4]; mPoints2[i * 4 + 1] = mPoints[i * 4]; mPoints2[i * 4 + 2] = mPoints[i * 4]; if (mPoints2[i * 4 + 3] > 0 && mPoints[i * 4 + 3] > mPoints2[i * 4 + 3] + downspeed) { mPoints[i * 4 + 3] = mPoints2[i * 4 + 3] + downspeed; upsetPoints[i * 4 + 3] = (getHeight() * 2 - mPoints[i * 4 + 3]) / 2 - downspeed / 2; } mPoints2[i * 4 + 3] = mPoints[i * 4 + 3]; } canvas.drawLines(mPoints, mForePaint); canvas.drawLines(upsetPoints, upsetPaint); } }
相关文章推荐
- Android 基于google Zxing实现对手机中的二维码进行扫描 学习
- android 使用proguard 代码混淆后,出现异常 Missing type parameter.
- android多设备界面适配的利器:属性weight的妙用
- 为cardslib添加长按滑动删除(Android)
- Android: Fragment的相关问题
- Android 自定义View
- 一个android应用效果开发引发的惨案(android Home按键)
- Android 自定义View及其在布局文件中的使用示例
- android自定义属性 format类型
- Android-->XmlPullParser
- 新手Android开发之二:onclicklistener到底怎么用?
- 编写Android.mk中的LOCAL_SRC_FILES的终极技巧
- android摄像头(camera)之 V4L2编程中用到的各种结构体
- Android 和 iOS 应用程序开发对比 [持续更新]
- android:基础进阶二:Timer的使用
- activity_main.xml 要用 Android Common XML Editor打开,双击的方式直接跳转到浏览器了
- Android中的AnimationDrawable(图片动画)介绍及使用
- android-boostrap
- Android、iOS和Windows Phone中的推送技术
- android 通过jni调用gsoap问题