package com.shine.analogoscilloscope; import java.util.ArrayList; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.media.AudioRecord; import android.view.SurfaceView; public class ClsOscilloscope { private ArrayList<short[]> inBuf = new ArrayList<short[]>(); private boolean isRecording = false;// 线程控制标记 private RecordThread rec; private DrawThread draw; /** * X轴缩小的比例 */ public int rateX = 4; /** * Y轴缩小的比例 */ public int rateY = 4; /** * Y轴基线 */ public int baseLine = 0; /** * 初始化 */ public void initOscilloscope(int rateX, int rateY, int baseLine) { this.rateX = rateX; this.rateY = rateY; this.baseLine = baseLine; } /** * 开始 * * @param recBufSize * AudioRecord的MinBufferSize */ public void Start(AudioRecord audioRecord, int recBufSize, SurfaceView sfv, Paint mPaint) { isRecording = true; rec = new RecordThread(audioRecord, recBufSize); rec.start();// 开始录制线程 draw = new DrawThread(sfv, mPaint); draw.start();// 开始绘制线程 } /** * 停止 */ public void Stop() { if(isRecording==true) { isRecording = false; inBuf.clear();// 清除 rec.stop(); draw.stop(); } } /** * 负责从MIC保存数据到inBuf * * @author GV * */ class RecordThread extends Thread { private int recBufSize; private AudioRecord audioRecord; public RecordThread(AudioRecord audioRecord, int recBufSize) { this.audioRecord = audioRecord; this.recBufSize = recBufSize; } public void run() { try { short[] buffer = new short[recBufSize]; audioRecord.startRecording();// 开始录制 while (isRecording) { // 从MIC保存数据到缓冲区 int bufferReadResult = audioRecord.read(buffer, 0, recBufSize); short[] tmpBuf = new short[bufferReadResult / (rateX)]; for (int i = 0, ii = 0; i < tmpBuf.length; i++, ii = i * rateX) { tmpBuf[i] = buffer[ii]; } synchronized (inBuf) {// inBuf.add(tmpBuf);// 添加数据 } } audioRecord.stop(); } catch (Throwable t) { } } }; /** * 负责绘制inBuf中的数据 * * @author GV * */ class DrawThread extends Thread { private int oldX = 0;// 上次绘制的X坐标 private int oldY = 0;// 上次绘制的Y坐标 private SurfaceView sfv;// 画板 private int X_index = 0;// 当前画图所在屏幕X轴的坐标 private Paint mPaint;// 画笔 public DrawThread(SurfaceView sfv, Paint mPaint) { this.sfv = sfv; this.mPaint = mPaint; } @SuppressWarnings("unchecked") public void run() { try{ while (isRecording) { ArrayList<short[]> buf = new ArrayList<short[]>(); synchronized (inBuf) { if (inBuf.size() == 0) continue; buf = (ArrayList<short[]>) inBuf.clone();// 保存 inBuf.clear();// 清除 } for (int i = 0; i < buf.size(); i++) { short[] tmpBuf = buf.get(i); SimpleDraw(X_index, tmpBuf, rateY, baseLine);// 把缓冲区数据画出来 X_index = X_index + tmpBuf.length; if (X_index > sfv.getWidth()) { X_index = 0; } } } }catch(Exception e){} } /** * 绘制指定区域 * * @param start * X轴开始的位置(全屏) * @param buffer * 缓冲区 * @param rate * Y轴数据缩小的比例 * @param baseLine * Y轴基线 */ void SimpleDraw(int start, short[] buffer, int rate, int baseLine) { if (start == 0) oldX = 0; Canvas canvas = sfv.getHolder().lockCanvas( new Rect(start, 0, start + buffer.length, sfv.getHeight()));// 关键:获取画布 canvas.drawColor(Color.BLACK);// 清除背景 int y; for (int i = 0; i < buffer.length; i++) {// 有多少画多少 int x = i + start; y = buffer[i]/ rate + baseLine;// 调节缩小比例,调节基准线 canvas.drawLine(oldX, oldY, x, y, mPaint); oldX = x; oldY = y; } sfv.getHolder().unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像 } } }
最近下载更多
lvjiang123 LV1
2021年5月22日
赵赵赵赵赵赵赵 LV1
2020年6月19日
z214658597 LV1
2019年4月13日
wqs-manson LV1
2019年3月11日
lzyChina LV1
2017年8月4日
jerry_xie_cn LV1
2017年7月20日
yy1069442142 LV1
2017年7月14日
saijirihu1234 LV9
2017年6月28日
SiriusYZZ LV3
2017年5月29日
rengle LV1
2017年5月24日
最近浏览更多
LITIANYU084414 LV11
2023年1月13日
wengzheng007 LV1
2022年11月22日
zhendong LV7
2022年9月25日
张恺祺 LV6
2022年5月21日
萌了个乖乖 LV12
2022年5月20日
GZW012345 LV8
2022年5月15日
dangzhiyuan012 LV12
2022年3月17日
lqf123 LV9
2021年6月14日
lvjiang123 LV1
2021年5月22日
lczd888 LV9
2021年5月8日