• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

SoundMeter: SoundMeter(分贝仪)

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

SoundMeter

开源软件地址:

https://gitee.com/wechart/SoundMeter

开源软件介绍:

SoundMeter(分贝仪)

我的个人主页

这是什么?

详细介绍

如果喜欢,请给我一个star

android端的声音检测程序,实时获取当前周围环境的声压级,也就是平常所说的分贝值

enter image description here

源码

声音采集利用系统的MediaRecorder

/** * 录音 * @return 是否成功开始录音 */public boolean startRecorder(){	if (myRecAudioFile == null) {		return false;	}    try {		mMediaRecorder = new MediaRecorder();		mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);		mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);		mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);		mMediaRecorder.setOutputFile(myRecAudioFile.getAbsolutePath());		mMediaRecorder.prepare();		mMediaRecorder.start();		isRecording = true;		return true;    } catch(IOException exception) {    	mMediaRecorder.reset();    	mMediaRecorder.release();    	mMediaRecorder = null;    	isRecording = false ;		exception.printStackTrace();    }catch(IllegalStateException e){    	stopRecording();		e.printStackTrace();		isRecording = false ;    }	return false;}  /**  * 获取声压值  */ public float getMaxAmplitude() {	 if (mMediaRecorder != null) {		 try {			 return mMediaRecorder.getMaxAmplitude();		 } catch (IllegalArgumentException e) {			 e.printStackTrace();			 return 0;		 }	 } else {		 return 5;	 } }

自定义显示分贝值得大圆盘View 取名SoundDiscView

private float scaleWidth, scaleHeight;private int newWidth, newHeight;private Matrix mMatrix = new Matrix();private Bitmap indicatorBitmap;private Paint paint = new Paint();static final long  ANIMATION_INTERVAL = 100;private void init() {    Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.noise_index);    int bitmapWidth = myBitmap.getWidth();    int bitmapHeight = myBitmap.getHeight();    newWidth = getWidth();    newHeight = getHeight();    scaleWidth = ((float) newWidth) /(float) bitmapWidth;  // 获取缩放比例    scaleHeight = ((float) newHeight) /(float) bitmapHeight;  //获取缩放比例    mMatrix.postScale(scaleWidth, scaleHeight);   //设置mMatrix的缩放比例    indicatorBitmap = Bitmap.createBitmap(myBitmap, 0, 0, bitmapWidth, bitmapHeight, mMatrix,true);  //获取同等和背景宽高的指针图的bitmap    paint = new Paint();    paint.setTextSize(55);    paint.setAntiAlias(true);    paint.setTextAlign(Paint.Align.CENTER);  //抗锯齿    paint.setColor(Color.WHITE);}@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    currentAngle = getAngle(World.dbCount); //获取指针应该显示的角度    mMatrix.setRotate(getAngle(World.dbCount), newWidth / 2, newHeight * 215 / 460);   //片相对位置    canvas.drawBitmap(indicatorBitmap, mMatrix, paint);    postInvalidateDelayed(ANIMATION_INTERVAL);    canvas.drawText((int)World.dbCount+" DB", newWidth/2,newHeight*36/46, paint); //图片相对位置}

启动、暂停与关闭

控制的所有操作全部在MainActivity里进行的,当启动或者重新进入activity时启动分贝仪,启动代码如下:

 @Overrideprotected void onResume() {    super.onResume();    bListener = true;    File file = FileUtil.createFile("temp.amr"); //创建录音文件    if (file != null) {        Log.v("file", "file =" + file.getAbsolutePath());        startRecord(file);    } else {        Toast.makeText(getApplicationContext(), "创建文件失败", Toast.LENGTH_LONG).show();    }}/** * 开始记录 * @param fFile */public void startRecord(File fFile){    try{        mRecorder.setMyRecAudioFile(fFile);        if (mRecorder.startRecorder()) {            startListenAudio();        }else{            Toast.makeText(this, "启动录音失败", Toast.LENGTH_SHORT).show();        }    }catch(Exception e){        Toast.makeText(this, "录音机已被占用", Toast.LENGTH_SHORT).show();        e.printStackTrace();    }}private void startListenAudio() {    thread = new Thread(new Runnable() {        @Override        public void run() {            while (isThreadRun) {                try {                    if(bListener) {                        volume = mRecorder.getMaxAmplitude();  //获取声压值                        if(volume > 0 && volume < 1000000) {                            World.setDbCount(20 * (float)(Math.log10(volume)));  //将声压值转为分贝值                            soundDiscView.refresh(); //子线程刷新view,调用了postInvalidate                        }                    }                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                    bListener = false;                }            }        }    });    thread.start();}

startListenAudio的执行过程就是开启一个线程,每隔一段时间获取分贝值然后刷新大圆盘,这里要注意的是在子线程操作刷新view的时候要用postInvalidate,查看postInvalidate的源码发现其原理很简单,它就是v用了一个handler机制,最终刷新肯定是在主线程的。

当activity被onStop时我们要停止与关闭录音采集,然后删除采集的文件,操作如下:

/** * 停止记录 */@Overrideprotected void onStop() {    super.onStop();    bListener = false;    mRecorder.delete(); //停止记录并删除录音文件} public void delete() {        stopRecording();		if (myRecAudioFile != null) {			myRecAudioFile.delete();			myRecAudioFile = null;		}   }

执行

整个效果还行,但是运行发现指针滑动的太突兀,做个缓慢过度

public static float dbCount = 40;private static float lastDbCount = dbCount;private static float min = 0.5f;private static float value = 0;public static void setDbCount(float dbValue) {	if (dbValue > lastDbCount) {		value = dbValue - lastDbCount > min ? dbValue - lastDbCount : min;	}else{		value = dbValue - lastDbCount < -min ? dbValue - lastDbCount : -min;	}	dbCount = lastDbCount + value * 0.2f ;	lastDbCount = dbCount;}

再次执行,perfect !


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap