做过音频相关的应该见过这种Eq曲线,每一个点都有一个影响范围,并对整体曲线有影响。
图片为前半部分。之前做的时候在网上并没有找到,Eq曲线的计算和画法。这里拿出来分享一下。这里只提供画图的方法,曲线的算法不在这里提供(公司资产)。如有需要请私聊。(本人也是翻译mathlib获取的)
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.iszcc.x5audio.bean.CarAudioConfig;
import com.iszcc.x5audio.bean.param.base.EQ;
import com.iszcc.x5audio.bean.param.base.FILTER;
import com.iszcc.x5audio.constans.Constants;
import com.iszcc.x5audio.eqcalc.CalcEqueal;
import com.iszcc.x5audio.eqcalc.EqParam;
import com.iszcc.x5audio.uitl.DataUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import static com.iszcc.x5audio.constans.Constants.EQ_freq;
import static com.iszcc.x5audio.constans.Constants.pointColor;
/**
* Created by DB on 2017/6/9.
*/
public class EQSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private static final String TAG = "SurfaceView";
//SurfaceHolder
private SurfaceHolder mHolder;
private byte passByte = 0;
//用于绘图的Canvas
private Canvas canvas;
//子线程标志位
private boolean mIsDrawing;
private Context mContext;
private Paint paintXy;//xy轴画笔
private Paint paintText;//文字画笔
private Paint mWrapPaint;//曲线笔
private Paint mPaintPoint;//
private Paint mPaintCurve;//主曲线笔
private Paint mPaintPass;// 显示EQ旁路的画笔
// 坐标轴上描述性文字的空间大小
private int mTopUnitHeight;// 顶部Y轴单位高度
private int mBottomTextHeight;//X轴底部字体的高度
private int mLeftTextWidth;
// 网格尺寸
private int mGridWidth, mGridHeight;
private int yHeight, xWeith;//x y 轴的长度
private ArrayList<Point> pointsList = new ArrayList<>();//点的集合
private Point hPFPoint = new Point();//高通点
private Point lPFPoint = new Point();//低通点
private boolean isDrawWrap = false;//是否画阴影的曲线
private boolean isDrawHLPF = false;//高低通
private CalcEqueal calcEqueal = CalcEqueal.getInstance();
//频响曲线
private double[] freqX = new double[1024];
private double[] freqY = new double[1024];
//x y 轴坐标值
private String[] xLineStr = new String[]{"-24dB", "-18dB", "-12dB", "-6dB", "0dB", "6dB", "12dB"};
private String[] yLineStr = new String[]{"20HZ", "50HZ", "100HZ", "200HZ", "500HZ", "1kHZ", "2kHZ", "5kHZ", "10kHZ", "20kHZ"};
//x轴什么所有线对应的频率值,对这些数取对数,在比上宽度值就是x坐标。
private float[] yLin = new float[]{
10,
20.0f, 30.0f, 40.0f,
50.0f, 60.0f, 70.0f, 80.0f, 90.0f,
100.0f,
200.0f, 300.0f, 400.0f,
500.0f, 600.0f, 700.0f, 800.0f, 900.0f,
1000.0f,
2000.0f, 3000.0f, 4000.0f,
5000.0f, 6000.0f, 7000.0f, 8000.0f, 9000.0f,
10000.0f,
20000.0f, 24000.0f};
public EQSurfaceView(Context context) {
super(context);
mContext = context;
initView();
}
public EQSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
}
public EQSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initView();
}
private void initView() {
mHolder = getHolder();
//添加回调
mHolder.addCallback(this);
{
mBottomTextHeight = dp2px(20);// X轴底部字体的高度
mLeftTextWidth = mBottomTextHeight;// Y轴左边字体的宽度
mTopUnitHeight = dp2px(20);// 顶部Y轴的单位
// 初始化坐标轴Paint
paintXy = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
paintXy.setStrokeWidth(dp2px(1));
paintXy.setColor(Color.parseColor("#71737171"));
// 初始化文本Paint
paintText = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
paintText.setColor(Color.GRAY);
paintText.setTextSize(sp2px(8));
//Eq 旁路的画笔
mPaintPass = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mPaintPass.setColor(Color.GRAY);
mPaintPass.setTextSize(sp2px(40));
// 初始化曲线Paint
mWrapPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
// mWrapPaint.setPathEffect(new CornerPathEffect(50f));//设置转角度数
//初始化主曲线笔
mPaintCurve = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
//画点
mPaintPoint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mPaintPoint.setColor(Color.RED);
mPaintPoint.setStrokeWidth(dp2px(2));
mPaintPoint.setStyle(Paint.Style.FILL);
}
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
//Surface的生命周期
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
isFristDraw = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int forma