android 音乐频谱
16lz
2021-01-24
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中的高效率的数据库操作框架----LitePal
- Android使用Intent实现页面跳转
- Android获取网络图片应用示例
- 初探Android中的请求服务器并解析返回的json数据
- Android(安卓)根据城市名称获取经纬度
- Android高级工程师成长路线
- Android程序开发之数据存储(一): 使用sqlite 进行登录注册
- Android解析XML(PULL)展示到ListView
- Android(安卓)压缩工具类